JVM的垃圾收集算法:标记-清除,复制,标记-整理,分代回收。

1.  “标记-清除”垃圾收集算法

“标记-清除”垃圾收集算法有两个阶段:标记 和 清除。

标记 是标记所有需要回收的对象,清除 是清除所有标记的回收对象。

缺点:

(1)会产生大量不连续的内存碎片,因为对象分配内存需要是连续的内存空间,如果对象太大,且没有足够大的连续内存空间,会触发垃圾回收。

(2)标记 和 清除效率也较低。

示意图如下图所示:

JVM的垃圾收集(GC)算法_内存碎片

2. “复制”垃圾收集算法

“复制”垃圾收集算法将内存分成两块。每次使用一块,当前块的内存快使用完了,就将当前块存活的对象复制到另外一个对象中。

优点:不用考虑内存碎片,只移动堆顶指针即可,按顺序分配内存即可,实现简单、高效。

缺点:内存缩小为原来的一半。

示意图如下图所示:

JVM的垃圾收集(GC)算法_内存碎片_02

新生代的对象朝生夕死(存活时间短),所以并不需要 1 :1 分成两块,可以将内存分为一块较大的 Eden 和两块较小的 Survivor  。HotSpot 中 Eden 和 Survivor  的比例为 8 : 1。每次使用  Eden 和 一块  Survivor  ,垃圾回收时将存活的对象复制到另一块  Survivor中。

虽说新生代的对象朝生夕死,但也不是一定,如过存活的对象超过 Survivor就会出现问题,需要其他内存(老年代)进行分配担保,类似于贷款。

3. “标记-整理”垃圾收集算法

“复制”垃圾收集算法适用于新生代,在老年代(存活时间较长)中效率很低。“标记-整理”垃圾收集算法适用于老年代,该算法分为两步标记需要被回收的对象,把存活的对象向一端移动。

优点:没有内存碎片。

示意图如下图所示:

JVM的垃圾收集(GC)算法_垃圾收集算法_03

4. “分代回收”垃圾收集算法

新生代,每次回收都有大量对象死去,可以使用“复制”。

老年代,存活率高,且没有额外空间担保,使用“标记-清理” 和 “标记-整理”。

参考文献

  • 深入理解Java虚拟机:JVM高级特性与最佳实践 / 周志明著. —— 2 版 . —— 北京:机械工业出版社,2013.6