垃圾回收算法
1> 引用计数法
- 增加引用 +1,失去引用 -1
- 存在循环引用问题
- JVM未选择此算法作为垃圾回收算法
2> 标记清除法
- 分为“标记”和“清除”两个阶段
- 标记:从根节点开始判断,存在引用标记为存活对象
- 清除:清除所有没有被标记的对象
缺点:产生大量的空间碎片
适用场景:老年代
3> 复制算法
- 将内存空间分为两块
- 标记存活的对象,将存活的对象复制移动到另外一块内存(B内存)空闲面上面,清除未存活对象(A内存)
- 缺点:系统内存只能使用1/2,需要复制移动对象
适用场景:年轻代
4> 标记压缩法
- 标记存活的对象,将所有存活的对象压缩到内存的一端,然后在清理所有存活对象之外的空间
5> 分区算法
- 将堆空间划分成连续的不同小区间,每个区间独立使用、回收
- 由于当堆空间大时,一 次GC的时间会非常耗时,那么可以控制每次回收多少个小区间
6> 分代回收算法
把堆分为新生代 和 老年代
- 新生代:
- Eden - S0 - S1 划分比例为 8:1:1
- 回收频率高耗时短
- 标记复制
- 老年代
- 回收频率低耗时高
- 标记压缩算法
- 标记清除算法 CMS
优势:对于新生代中使用标记复制算法,可以使用的空间为 Eden + S0 = 8 + 1 = 90%
新生代垃圾回收
- Eden + S0 内存不足,就会触发GC(Minor gc/young gc),这时就会根据 GC Roots 标记存活对象,把存活对象复制到 S1,此时存活对象年龄加1,清除 Eden + S0 未存活的对象 。
- GC后S0区域被清空。S0和S1发生了互换,S1变成了From Survivor,S0变成了To Survivor(To Survivor区永远都为空)
老年代垃圾回收
- 随着年轻代对象的不断晋升,老年代的对象变得越来越多,达到容量阈值后老年代也会发生垃圾回收,我们称之为Major GC或者Full GC,Full GC并不是全局GC,它只发生在老年代。
晋升机制
- 设置 OldObject -XX:MaxTenuringThreshold=15
- 每经历一次gc存活的对象分代年龄+1达到15进入老年代
- 设置 BigObject -XX:PretrnureSizeThreshold=0 大对象直接进入 老年代
- 如果参数被设置成5MB,超过5MB的大对象会直接分配到老年代
- 注意:PretenureSizeThreshold参数只对Serial和ParNew两种回收器有效
- 动态对象年龄判定
- Survivor空间中相同年龄对象大小的总和大于Survivor空间的一半,以及相比它年龄更大的对象都会被晋升到老年代
近期评论