GC-垃圾回收算法

标记-清除算法

  • 分为“标记”和“清除”两个阶段

    • 标记阶段:
      标记的过程其实就是前面介绍的可达性分析算法的过程,遍历所有的GC Roots对象,对从GC Roots对象可达的对象都打上一个标识,一般是在对象的header中,将其记录为可达对象
    • 清除阶段:
      清除的过程是对堆内存进行遍历,如果发现某个对象没有被标记为可达对象(通过读取对象header信息),则将其回收
  • 不足

    • 标记和清除效率都不高

    • 标记、清除之后会产生大量不连续的内存碎片

复制算法(新生代)

对象存活率低,且有老年代分配担保,因此常采用复制算法

  • Eden:Survivor:Survivor=8:1:1
    在这里插入图片描述

  • 分配担保

    如果Survivor没有足够空间来存放上次新生代GC存活下来的对象,它们将通过分配担保机制进入老年代

  • 不足

    • 将内存缩小为原来的一半,浪费了一半的内存空间,代价太高;如果不想浪费一半的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法

    • 复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低

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

对象存活率高,且没有额外空间对它进行分配担保,因此常用标记清除或标记整理算法来实现

  • 先执行标记-清除,让所有的存活对象都向一端移动,最后清理掉边界以外的内存
  • 不足
    • 效率不高,不仅要标记存活对象,还要整理所有存活对象的引用地址,在效率上不如复制算法

分代收集算法

复制算法和标记整理法的结合

标记-压缩算法

标记阶段和之前的标记-清除中提到的标记阶段完全一样,然后我们就通过遍历数次堆来进行压缩。这里的压缩指的就是复制-清除里面的把存活对象重新装填,使对象都紧挨在一起,从而避免内存碎片的产生,同时保证内存的高速分配。不过与GC复制算法不同的是,标记-压缩不需要牺牲额外的空间

猜你喜欢

转载自blog.csdn.net/weixin_45937536/article/details/128253074