JAVA垃圾收集过程(2)

    大家好,上次和大家分享了JAVA垃圾回收过程的第一个步骤:如何判断对象是否需要回收,今天我们来分享如何进行垃圾回收。

    在JVM中,进行垃圾回收主要有以下几种方式:

    1.标记-清除算法。

    2.复制算法。

    3.标记-整理算法。

    4.分代收集算法。

    下面我们来分别具体介绍:

    1.标记-清除算法:

    标记-清除算法是最基础的收集算法,该算法分成两个过程:标记过程和清除过程。

    首先标记出所有需要收集的对象,在标记完成后触发垃圾回收,标记过程就是上一篇中我们所讲的,如何判断对象需要收集的过程。但是这种算法存在两个明显的问题。

    第一个问题是效率问题。在这种算法中,标记和清除阶段的效率都不是很高。第二个问题就是空间问题,这种算法在标记清除之后会产生大量的内存碎片,也就是大量的可使用的小空间,但是这种小空间数量如果太多会导致程序在为大对象分配内存空间时无法找到合适的内存,从而会触发另外一次垃圾回收过程。

    2.复制算法:

    由于标记-整理算法所存在的效率和空间问题,产生了第二种算法:复制算法。原理是将内存划分为相等的两块,每次只使用其中的一块,在第一块内存使用完之后,触发一次垃圾回收,将还存活的对象复制到另外一块内存中去,然后将第一块已使用的内存全部清除掉,之后的内存分配发生在第二块中,当第二块使用完成后,继续重复上述步骤。

    这样就不需要考虑内存碎片问题,而且每次只回收其中的一块内存,也让效率得到了提高。

    但是这种算法的代价就是将内存分成了两块,每次只能使用其中一块,所以在后来的分代算法中,只使用这种算法来回收新生代,而且两块内存的分配也不是各占一半,这个我们在分代收集算法中讲解。

    3.标记-整理算法:

    复制算法虽然解决了一些问题,但是在对象存活率较高的情况下就需要进行较多的复制操作,效率会变低,更重要的是如果我们不愿意浪费一半的空间,就需要分配额外的空间来做内存担保,以应对使用的内存中对象100%存活的极端情况。

    在这种情况下,有人提出标记-整理算法,这种算法也是分为两个阶段:标记阶段和整理阶段。标记阶段我们不再详细解释,所谓的整理阶段,就是在标记完成之后,让所有存活的对象在内存中向一边移动,将死亡对象挤出内存。

    4.分代收集算法:

    其实分代收集算法是以上标记-整理算法和复制算法的结合:根据对象存活周期将java堆内存分为年轻代和老年代,年轻代使用复制算法,将年轻代分为一个Eden区和两个Survivor区,内存占比大体为8:1:1,每次只使用Eden区和一个Survivor区,在需要回收时,就将存活的对象全部移动到另外一个Survivor区,然后清除掉Eden区和第一个Survivor区。之所以在年轻代中选择使用复制算法,是因为在年轻代中的对象大多是朝生夕死的对象,存活率比较低,所以可以付出少量的内存作为代价进行回收。但是老年代中对象的存活率相对于年轻代较高,也不存在额外的空间进行内存担保,所以就使用标记整理算法进行收集。

    那么年轻代和老年代的对象是怎么划分和转换的呢?这里我们留一个悬念,下一篇再和大家分享。

    今天就和大家分享这些知识,如果大家觉得我们的文章对您有用,请关注我们的公众号,每天一篇干货文章和实用面试题哦。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值