【JVM】垃圾收集2-垃圾收集算法

大部分内容转自https://zhuanlan.zhihu.com/p/25539690
作者:韦庆明

垃圾收集算法(4种)

  为了更好的提高GC的性能HotSpot JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to),默认比例为8:1。
关于Eden与Survior的解释请看:https://blog.csdn.net/lojze_ly/article/details/49456255

一、标记-清除算法

这里写图片描述
  标记-清除算法采用从根集合进行扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未被标记的对象进行直接回收,如上图。
  标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活的对象比较多的情况下极为高效,但由于标记-清除算法直接回收不存活的对象,并没有对还存活的对象进行整理,因此会导致内存碎片。

  • 缺点:
    • 1.效率问题 -标记和清除的过程效率并不高 (递归与全堆对象遍历)
    • 2.空间问题 -标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致,当程序在以后的运行过程中无法找到足够的连续内存不得不提前触发另一次的GC动作。

二、复制算法(常用回收新生代)

这里写图片描述
  复制算法将内存划分为两个区间,使用此算法时,所有动态分配的对象都只能分配在其中一个区间(活动区间),而另外一个区间(空间区间)则是空闲的。
  复制算法采用从根集合扫描,将存活的对象复制到空闲区间,当扫描完毕活动区间后,会的将活动区间一次性全部回收。此时原本的空闲区间变成了活动区间。下次GC时候又会重复刚才的操作,以此循环。
  复制算法在存活对象比较少的时候,极为高效,但是带来的成本是牺牲一半的内存空间用于进行对象的移动。所以复制算法的使用场景,必须是对象的存活率非常低才行,而且最重要的是,我们需要克服50%内存的浪费。

三、标记-整理算法(常用回收老年代)

这里写图片描述
  标记过程与标记清除类似,但后续步骤不是直接对可回收对象进行清理,让所有存活对象都向一端移动,然后清理掉端边界以外的内存。
  标记-整理 算法是在标记-清除算法之上,又进行了对象的移动排序整理,因此成本更高,但却解决了内存碎片的问题。

四、分代收集算法

  这种算法只是根据对象存活周期不同将内存区域划分为几块,一般是把JAVA堆分为新生代和老年代。

  • 新生代 :新生代每次垃圾收集是都发现有大批对象死去,只有少量存活,所以对于新生代采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集
  • 老年代 :因老年代对象存活率高,则使用标记清理标记整理算法来回收

  JVM为了优化内存的回收,使用了分代回收的方式,对于新生代内存的回收(Minor GC)主要采用复制算法。而对于老年代的回收(Major GC),大多采用标记-整理算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值