开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 24 天,点击查看活动详情
前言
之前一篇文章,我们了解了 Java 垃圾回收算法中的标记-清除法、标记-复制法 聊聊 Java 垃圾回收算法(一),今天我们来一起看看 Java 的另外两种垃圾回收算法。
标记-整理法
标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。另外,如果不想浪费 50% 的内存空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都 100% 存活的极端情况,所以在老年代一般不能直接选用这种算法。
针对老年代对象的存亡特征,出现了一种标记-整理算法,其中的标记过程仍然与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存,如图所示:
标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法,而后者是移动式的。
我们总结来看,标记整理法的优点有:
- 相比标记清除法,能够避免产生空间碎片
- 相比标记复制法,能够更大程度地利用内存空间,不会造成 50% 的内存浪费
不过,它还是有一定的缺点:
- 如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,移动存活对象并更新所有引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序才能进行,这种现象被称为 “Stop The World”。
分代收集理论
-
部分收集(Partial GC):指目标不是完整收集整个 Java 堆的垃圾收集,其中分为:
- 新生代收集(M inor GC/Young GC): 指目标只是新生代的垃圾收集
- 老年代收集(Major GC/Old GC): 指目标只是老年代的垃圾收集。
- 混合收集(Mixed GC): 指目标是收集整个新生代以及部分老年代的垃圾收集。
-
整堆收集(Full GC): 收集整个 Java 堆和方法区的垃圾收集。