垃圾收集算法

垃圾收集算法

标记清除法

复制算法

标记整理法

标记清除法(Mark-Sweep)算法分成标记和清除两个阶段,先标记出要回收的对象,然后统一回收这些对象。

优点是简单

缺点:效率不高,标记和清除的效率都不高

标记清除过后会产生许多大量不连续的内存碎片,从而导致在分配大对象时触发GC

复制算法(Copying):把内存分成两块完全相同的区域,每次使用其中的一块,当一块使用完了,就把这块上还存活的对象拷贝到另外一块,然后把这块清除掉

优点:实现简单,运行高效,不用考虑内存碎片的问题

缺点是:内存有些浪费

JVM实际实现中,是将内存分为一块较大的Eden区和两块较小的Survivor空间,每次使用Eden和一块Survivor,回收时,把存活的对象复制到另一块Survivor。

HotSpot默认的Eden和Survivor比是8:1,也就是每次能用90%的新生代空间

如果Survivor空间不够,就要依赖老年代进行分配担保,把放不下的对象直接进入老年代

分配担保:

当新生代进行垃圾回收后,新生代的存活区放置不下,那么需要把这些对象放置到老年代去的策略,也就是老年代为新生代的GC做空间分配担保,步骤如下:

  1. 在发生MinorGC前,JVM会检查老年代的最大可用的连续空间,是否大于新生代所有对象的总空间,如果大于,可以确保MinorGC是安全的。
  2. 如果小于,那么JVM会检查是否设置了允许担保失败,如果允许,则继续检查老年代最大可用的连续空间,是否大于历次晋升到老年代对象的平均大小

2.1 如果大于,则尝试进行一次 MinorGC

2.2 如果不大于,则改做一次 Full GC

标记整理法

标记整理算法(Mark-Compact):由于复制算法在存活对象比较多的时候,效率较低,且有空间浪费,因此老年代一般不会选用复制算法,老年代多选用标记整理算法

标记过程跟标记清除一样,但后续不是直接清除可回收对象,而是让所有存活对象都向一端移动,然后直接清除边界以外的内存

---- The end of this article ----