JVM之GC常见算法

  1. 引用计数法(很少用):
    JVM之GC常见算法
    使用一个计数器对堆中的对象被引用的次数进行统计,将没有被引用的对象进行清除

2.复制算法

JVM之GC常见算法

  • 每次GC都会讲Eden区中的对象清到幸存区中,一旦Eden区被GC,那么Eden区就会是空的
  • 两个幸存区保持谁空谁是to的原则,即每次GC回将上一轮的from区中的对象复制,然后加上Eden区中新的被GC进来的对象,合在一起放入空的to区中,然后to区变成下一轮的from区,原来的from区被清空,变成新一轮的to区
  • 当一个对象经历了15次(默认值)GC还没有死,那么就会进入养老区中
    注:可通过-XX:MaxTenuringThreshold +value 来调节进入养老区的时间,这也是JVM性能调优的一种方式

优点:没有内存碎片
缺点:浪费了内存空间,多了一半空间为空,加入存活率100%就会发生OOM,所以复制算法常用与存活率较低的新生区中

3.标记清除算法

  • 第一次扫描标记存活对象

    JVM之GC常见算法

  • 第二次扫描清除没有被标记的对象

    JVM之GC常见算法

优点:不需要额外空间

缺点:时间复杂度高,有内存碎片

4.标记压缩算法

前两步和标记清除算符一致

但是多了第三部,将存活对象移动到一起

JVM之GC常见算法

优点:不需要额外空间,没有内存碎片

缺点:时间复杂度更高

二、总结

内存效率:复制算法>标记清除算法>标记压缩算法

内存整齐度: 复制算法=标记压缩算法>标记清除算法

内存利用率:标记压缩算法=标记清除算法>复制算法

所以,没有最好的算法,只有最合适的算法!所以JVM的GC=分代收集算法

  • 年轻代存活率低,所以用复制算法,效率高

  • 老年代存活率高,所以用标记压缩(内存碎片多的时候用)+标记清除算法(内存碎片不多的时候用)