JVM垃圾处理方法

1、标记-清除算法(老年代)

该算法分为“标记”和“清除”两个阶段:

首先标记出所有需要回收的对象(可达性分析), 在标记完成后统一清理 掉所有被标记的对象

 该算法会有两个问题:

1. 效率问题,标记和清除效率不高。

2. 空间问题: 标记清除后会产生大量不连续的内存碎片, 空间碎片太多可能会导致在运行过程中需要分 配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集。 所以它一般用于"垃圾不太多的区域,比如老年代"。

2、复制算法(新生代) 该算法的核心是将可用内存按容量划分为大小相等的两块, 每次只用其中一块, 当这一块的内存用完, 就将 还存活的对象(非垃圾)复制到另外一块上面, 然后把已使用过的内存空间一次清理掉。

优点:不用考虑碎片问题,方法简单高效。

缺点:内存浪费严重。

现代商用VM的新生代均采用复制算法,但由于新生代中的98%的对象都是生存周期极短的,因此并不需 完全按照1∶1的比例划分新生代空间,而是将新生代划分为一块较大的Eden区和两块较小的Survivor区 (HotSpot默认Eden和Survivor的大小比例为8∶1), 每次只用Eden和其中一块Survivor。

当发生MinorGC时,将Eden和Survivor中还存活着的对象一次性地拷贝到另外一块Survivor上, 最后清 理掉Eden和刚才用过的Survivor的空间。当Survivor空间不够用(不足以保存尚存活的对象)时,需要依赖 老年代进行空间分配担保机制,这部分内存直接进入老年代。

 复制算法的空间分配担保:

在执行Minor GC前, VM会首先检查老年代是否有足够的空间存放新生代尚存活对象, 由于新生代使用复 制收集算法, 为了提升内存利用率, 只使用了其中一个Survivor作为轮换备份, 因此当出现大量对象在 Minor GC后仍然存活的情况时, 就需要老年代进行分配担保, 让Survivor无法容纳的对象直接进入老年代, 但前提是老年代需要有足够的空间容纳这些存活对象.

但存活对象的大小在实际完成GC前是无法明确知道的, 因此Minor GC前, VM会先首先检查老年代连续空 间是否大于新生代对象总大小或历次晋升的平均大小, 如果条件成立, 则进行Minor GC, 否则进行Full GC(让老年代腾出更多空间).

然而取历次晋升的对象的平均大小也是有一定风险的, 如果某次Minor GC存活后的对象突增,远远高于平 均值的话,依然可能导致担保失败(Handle Promotion Failure, 老年代也无法存放这些对象了), 此时就只 好在失败后重新发起一次Full GC(让老年代腾出更多空间).

3、标记-整理算法(老年代)

标记清除算法会产生内存碎片问题, 而复制算法需要有额外的内存担保空间, 于是针对老年代的特点, 又有 了标记整理算法. 标记整理算法的标记过程与标记清除算法相同, 但后续步骤不再对可回收对象直接清理, 而是让所有存活的对象都向一端移动,然后清理掉端边界以外的内存.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值