垃圾收集算法

一、标记-清除算法

    该算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象。该算法有两个不足之处:一个是效率问题,标记和清除两个过程的效率不高,另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时候,无法找到足够的连续内存而不得不提现触发一次垃圾收集动作。


二、复制算法

    为了解决效率问题,复制算法出现了,它将内存分为大小相等的两块,每次只使用其中的一块。当这一块用完了就将还存活的对象复制到另一块上去,然后再将已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时候也就不用考虑碎片等复制情况。但是这种算法代价是内存缩小为原来的一半。

    现在的商用虚拟机都是用这种方法来回收新生代,因为新生代的对象“朝生夕死”所以不需要按照1:1的比例来分配内存空间,而是将空间化分为Eden和两块较小的Survivor空间,每次使用Eden和其中一块Survivor空间,最后清理掉Eden和刚才用过的Survivor空间。HotSpot中默认Eden:From Survivor0:To Survivor1的比例为8:1:1,也就是说每次新生代可用内存是整个新生代的90%(8+1),只有10%的内存会被“浪费”。当然,我们没办法保证每次回收都只有不多余10%的对象存活,当To Survivor1空间不够用时候需要依赖其他内存(这里指的是老年代)进行分配担保。


三、标记-整理算法

    复制收集算法在对象存活较多的场景下会进行多次复制,效率降低。更关键是,如果不想浪费50%的内存我们需要有额外的空间进行分配担保,以应对被使用的内存中所有的对象都100%存活的极端情况,所以老年代不能直接使用复制算法。

    根据老年代的特点,有人提出了另外一种“标记-整理”算法,标记过程和“标记-清除”算法一样,只是标记后不是直接清理,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。


四、分代收集思想

    当前商业虚拟机采用的都是“分代收集”算法,根据对象的存活周期不同将内存划分为几块。Java堆化分为新生代和老年代,因为新生代的对象大部分都是“朝生夕死”所以采用复制算法,而老年代对象存活率高,没有额外的空间分配担保,就必须使用标记-清除或者标记-整理算法来进行回收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值