JVM垃圾收集算法

JVM垃圾收集算法教程

JVM 垃圾收集算法主要包括:标记清除算法、赋值算法、标记整理算法和分代回收算法。

JVM标记清除算法

标记清除算法是最基本的垃圾收集算法,包含 “标记——清除” 两个操作。首先会标记出需要回收的对象,在标记完成后统一的回收所有被标记的对象。

标记清除过程先将可以回收的对象打上标记,然后对可以回收的对象进行回收。执行过程如下图:

02_标记清除算法回收前.png

回收后状态如下图:

03_标记清除算法回收后.png

从上面的转换过程来看有以下缺点:

  1. 标记的过程和清除的过程,两个过程效率都不高。
  2. 磁盘碎片问题,可以发现,回收后的状态,虽然有很多未使用的磁盘,但是不是连续的,导致遇到大对象后还要继续回收空间。

JVM复制算法

复制算法将内存分称两个相等的空间,每次只使用其中的一个空间。当这个空间内存用完了,就将还活着的对象复制到另外一个空间上面,然后将自己已经使用的空间一次清理掉。

这样就使得每次对半个区域进行内存回收,内存分配的时候就不需要考虑碎片的问题,因为半边区域中剩下的和使用的区域都是连续的。复制算法执行过程如下图:

04_复制算法回收前.png

回收后状态如下:

05_复制算法回收后.png

从上面操作过程看到始终有半个区域的内存空间是浪费的,不被使用的。

JVM标记整理算法

标记整理算法和标记清除算法一样,是先标记再清除,但是整理这边,是将存活的对象往前移动,将需要被清除的空间占据。所有的活着的对象占用的空间就是有效被占用空间,剩下的空间内存就会被直接清理掉。标记整理算法过程如下图:

06_标记整理算法前.png

标记整理算法后状态如下:

07_标记整理算法后.png

JVM分代回收算法

当前的商业虚拟机都采用的是分代收集算法,分代收集算法将堆分成新生代和老年代。新生代里面分为 Eden 区和两个 Survivor 区。新生代在每次垃圾回收的时候都有大量的对象被回收,而老年代只有少量的对象被回收。

当一个对象的大小大于新生代的空间时,会将该对象直接存放到老年代中,或者在新生代里面存活的周期达到一定的阀值的时候,也会被移动到老年代中。新生代的垃圾回收机制使用的是复制回收算法。

老年代中使用的是 “标记-整理” 算法。分代回收算法如下图:

08_分代回收算法.png