JVM(三)JVM的垃圾回收算法

前言

      本章讲解JVM中的垃圾回收算法的基本原理

方法

1.概念

我们知道,在程序运行过程中,Java堆不断的产生对象,也因此成为了垃圾回收器重点工作的区域。

既然需要进行垃圾回收,那么就有必要知道JVM内部是如何进行垃圾回收的,一般有以下算法进行垃圾回收:

引用计数算法、复制算法、标记清除算法、标记整理算法、分代收集算法

其中分代回收算法在JVM中较为常用!

2.引用计数算法

Java在运行时,当有一个地方引用该对象实例,会将这个对象实例加1,引用失效时就减1,JVM在扫描内存时,发现引用计数值为0的则是垃圾对象,计数值大于0的则为活跃对象。

目前垃圾回收算法,没有采用引用计数算法,原因是在对象互相引用的情况下,无法判定两者是否为垃圾对象。

3.复制算法

此算法将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。

但这样的代价就是牺牲了一半的内存,成本太高。 

JVM(三)JVM的垃圾回收算法_第1张图片

4.标记清除算法

最基础的收集算法是“标记-清除”(Mark-Sweep)算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

标记-清除算法是最基础的收集算法,其他的收集算法都是基于这种思路并对其不足进行改进而得到的。

这种算法的缺点也很明显,一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

JVM(三)JVM的垃圾回收算法_第2张图片

5.标记整理算法

为了缓解标记清除算法带来的负面效应,产生了标记整理算法。

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

该算法的优势也是特别的明显,但在处理新生代区域时不时特别适合。

JVM(三)JVM的垃圾回收算法_第3张图片

6.分代回收算法

目前JVM常用回收算法就是分代回收,年轻代以复制算法为主,老年代以标记整理算法为主。原因是年轻代对象比较多,每次垃圾回收都有很多的垃圾对象回收,而且要尽可能快的减少生命周期短的对象,存活的对象较少,这时候复制算法比较适合,只要将有标记的对象复制到另一个内存区域,其余全部清除,并且复制的数量较少,效率较高;而老年代是年轻代筛选出来的对象,被标记比较高,需要删除的对象比较少,显然采用标记整理效率较高。

JVM(三)JVM的垃圾回收算法_第4张图片

你可能感兴趣的:(JVM)