JVM垃圾回收机制&&垃圾回收器

75 阅读3分钟

垃圾回收算法

  • 可达性分析算法:通过可达性分析算法判断对象是否活着,是否可以回收,当GCRoots没有通向当前对象节点的链路时候,就代表对象可以被回收。

    • GCRoots节点
      • 虚拟机栈引用的对象
      • 本地方法栈引用的Native对象
      • 方法区中常量、静态变量引用的对象
  • 标记-整理:标记后,将使用中的对象向一端移动,然后清除这一端边界以外的内存

  • 标记-清除:将可回收对象做一个标记,然后清除掉所有被标记的对象

    • 时间上效率低下
    • 空间上会产生大量不连续的内存碎片
  • 复制-算法:多用于新生代,有Eden,survivor,老年代三个主要的区域

    • GC开始时,对象只存活在Eden区和Survivor中的from区中,survivor中的to区是空的
    • 接着进行GC,Eden中所有的存活的对象都被移动到to区中
    • from区中根据存活对象的年龄决定去向,如果大于一定年龄的对象被移动到老年代中,小于一定年龄的对象被移动到to区中
    • 请空Eden区以及from区,此时from区与to去交换,必须保证to区是空的
    • 重复以上过程,直到to被填满,将所有的对象都移动到老年代中

垃圾回收器

------新生代收集器--------------------

  • Serial:只会用一个cpu或者一个线程进行垃圾回收,运行时需要stop the world,也就是需要停止其他的用户线程。

  • ParNew:是serial收集器的多线程版本,除了多线程的垃圾回收之外,其余的与serial相同

  • Parallel Scavange:是并行的、多线程的收集器

    • 其希望达到一个可控的吞吐量
    • 吞吐量=用户工作线程时间/(用户工作线程时间+垃圾回收时间)

------老年代收集器--------------------

  • CMS

    • 标记-清除算法
    • 初始标记
      • 仅仅标记直接与GC Roots相连的对象,速度很快,需要stop the world
    • 并发标记
      • 按照GC Roots连路往下标记,此时用户线程也工作,不需要stop the world
    • 重新标记
      • 将并发标记中因为用户工作程序而导致标记产生变动的那一部分对象纠正,需要stop the world
    • 并发清除
      • 清除掉标记的对象,不需要stop the world,与其他的用户线程一起工作。
  • Parallel Old

    标记-整理算法

    parallel Scavange的老年代算法

  • Serial Old

    标记-整理算法

    单线程

--------兼----------------------------

  • G1

    • 不需要其他垃圾收集器的配合就能独立管理这个GC堆
    • 整体看是标记整理,局部是复制算法
    • 运行期间不会产生内存碎片,垃圾收集后提供规整的可用的内存
    • 建立了一个可预测的停顿时间模型,使用者可以指定在长为M ms的时间段,消耗在GC上的不超过N ms
    • 初始标记、并发标记、最终标记、筛选回收四个阶段

image.png