【jvm】Java虚拟机(jvm)垃圾回收算法(GC)整理

时间:2023-01-02 23:17:33
1、标记-清除算法

步骤 ======= 该算法分为“标记”和“清除”两个阶段,遍历GC Roots,首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。

缺点 ======= 首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。



2、复制算法

步骤 ======= 该算法将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。

缺点 ======= 可使用的内存降为原来一半。



3、标记-整理算法

步骤 ======= 该算法是遍历GC Roots,先标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,

在移动过程中清理掉可回收的对象。

缺点=======效率不高,不仅要标记所有存活对象,还要整理所有存活对象的引用地址。



4、分代收集算法

步骤 ======= 该算法是根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。

新生代分为Eden区,Survivor from和Survivor to三部分,其占新生代内存容量默认比例分别为8:1:1。当新生代内存空间不足需要进行垃圾回收时,仍然存活的对象被复制到空白的Survivor内存区域中,Eden和非空白的Survivor使用标记-清理回收算法,两个Survivor区域是轮换的。

年老代中的对象一般都是长生命周期对象,对象的存活率比较高,因此在年老代中使用标记-整理垃圾回收算法。

永久代也使用标记-整理算法。

当新生代中无足够空间为对象创建分配内存,年老代中内存回收也无法回收到足够的内存空间,并且新生代和年老代空间无法在扩展时,堆就会产生OutOfMemoryError异常。

Minor GC : 新生代收回内存
Major GC : 老年代回收内存
Full    GC : 清理整个堆空间,包括新生代和老年代。


触发JVM执行Full GC的条件
1、统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间;
2、老年代内存空间不足;
3、永久代内存空间不足;
4、CMS GC时出现promotion failed和concurrent mode failure;