天天看点

JVM笔记05.Garbage Collection

本文主要基于周志明老师的《深入理解Java虚拟机》。

文章目录

    • Garbage Collection
      • 哪些内存需要被回收?
        • 引用计数算法 Reference Count
        • 可达性分析算法 Root Searching
        • 三色标记清除算法 Tri-color Marking
          • 增量更新 Incremental Update
          • 原始快照 Snapshot At The Beginning
      • 垃圾回收算法
        • 标记清除 Mark-Sweep
        • 拷贝 Copying
        • 标记压缩 Mark-Compact
        • 标记-清除-压缩 Mark-Sweep-Compat
      • 基于分代的垃圾回收
        • JVM内存分代模型
        • HotSpot中默认配置
        • MinorGc、MajorGC、YGC、FGC
        • 卡表 Card Table
      • 垃圾收集器
        • Serial
        • Serial Old
        • Parallel Old
        • Parallel Scavenge
        • ParNew
        • CMS
        • G1
        • Shenandoah
        • Epsilon
        • ZGC
        • JVM指定垃圾收集器
      • 拓展阅读

Garbage Collection

  自Java引入垃圾回收以来,垃圾回收器的发展就未停止过。在JDK11种引入了ZGC,在JDK12种又引入了Shenandoah。虽然新的垃圾回收器不断地涌现,但是垃圾回收的基础算法变化并不大。简单来说,回收算法主要有复制、标记清除、标记压缩。

  垃圾回收可以分为三个问题:哪些内存需要被回收?什么时候去回收?如何回收?

哪些内存需要被回收?

  简单的说,没有任何引用指向的一个对象或者循环引用的多个对象。需要被回收。目前垃圾回收算法主要有两类,引用计数法和可达性分析算法。JVM的垃圾回收采用了可达性分析法。

引用计数算法 Reference Count

  在堆内存中分配对象时,会为对象分配一段额外空间。这段空间用于记录引用计数,当对象增加了一个新的引用,则将增加计数器的值。如果一个引用关系失效,则减少计数器的值。当一个对象的计数器的值变成0,则说明该对象已经被废弃,处于不活跃状态,可以被回收。引用计数法存在无法回收循环引用的问题,并且并发计数需要上锁效率低。Python语言中使用的便是引用计数法。

可达性分析算法 Root Searching

通过一组根对象根据引用链向下标记,没有被标记到的对象被称为不可达,证明此对象可被回收。

三色标记清除算法 Tri-color Marking

三色标记清除算法

https://www.bilibili.com/video/BV1KU4y1Y7cu

增量更新&SATB

https://www.bilibili.com/video/BV1Uz4y1S798

三色标记清除算法中用三种颜色来区分不同的内存节点。

  • 白 没有遍历到的节点。
  • 灰 自己标记完成,还没来得及标记子节点。
  • 黑 自己标记完成,子节点都标记完成。

并发标记导致的"对象消失"问题,当且仅当以下两个条件同时满足时,会产生“对象消失”的问题,即原来应该是黑色的对象被误标成了白色。

  • 赋值器插入一条或多条从黑色对象到白色对象的新引用。
  • 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。

对此分别有两种解决方案,增量标记(Incremental Update)和原始快照(SATB)。

增量更新 Incremental Update

在JVM中,CMS采用的是增量标记。

增量更新破坏了第一个条件,可以简化理解为把黑色重新标记为灰色,下次重新扫描子节点。

原始快照 Snapshot At The Beginning

在JVM中,G1采用原始快照。

原始快照破坏了第二个条件,可以简化理解为无论引用关系删除与否,都会按照刚开始扫描那一刻的对象图快照来进行搜索。

垃圾回收算法

标记清除 Mark-Sweep

JVM笔记05.Garbage Collection

标记清除

位置不连续 产生碎片 效率偏低(两遍扫描)

拷贝 Copying

JVM笔记05.Garbage Collection

拷贝

没有碎片,浪费空间

标记压缩 Mark-Compact

JVM笔记05.Garbage Collection

标记压缩

没有碎片,效率偏低(两遍扫描,指针需要调整)

标记-清除-压缩 Mark-Sweep-Compat

多次GC后才压缩,是标记清除和标记压缩的结合。

基于分代的垃圾回收

基于分代的垃圾回收的本质就是分代假说。弱分代假说(weak generational hypothesis)的含义是:大多数对象都在年轻时死亡。强分代假说(strong generational hypothesis)的含义是:越老的对象越不容易死亡。

更多内容请参考《垃圾回收算法手册:自动内存管理的艺术》。

JVM内存分代模型

JVM笔记05.Garbage Collection

HotSpot虚拟机的垃圾收集器

除Epsilon、ZGC、Shenandoah之外的垃圾收集器都是使用逻辑分代模型。G1采用逻辑分代物理不分代,所以可以同时用于传统意义上的年轻代和老年代。除此之外的垃圾收集器不仅逻辑分代还物理分代。

HotSpot中默认配置

新生代 :老年代 = 1 : 3

新生代 = Eden + Suvivor0 + Suvivor1

Eden :Suvivor0 :Suvivor1 = 8 :1 :1

MinorGc、MajorGC、YGC、FGC

YGC = Young GC = MinorGC

FGC = Full GC = MajorGC

卡表 Card Table

垃圾回收跨代引用/卡表/写屏障

https://www.bilibili.com/video/BV1Jy4y1p7t8

执行YGC时,需要扫描整个老年代,效率非常低,所以JVM设计了CardTable。如果一个老年代CardTable中有对象指向年轻代,就将它设为Dirty,下次扫描时,只需要扫描Dirty Card。

在数据结构上,Card Table用BitMap来实现。

垃圾收集器

Serial

Serial是一个stop-the-world,基于拷贝算法的单GC线程年轻代垃圾收集器。

Serial Old

Serial Old是一个stop-the-world,基于mark-sweep-compact(MSC)算法的单GC线程老年代垃圾收集器。

Parallel Old

Parallel Old是一个stop-the-world,基于压缩算法的多GC线程老年代垃圾收集器。

Parallel Scavenge

Paralledl Scavenge是一个stop-the-world,基于拷贝算法的多GC线程年轻代垃圾收集器。

ParNew

在ParNew在Paralledl Scavenge之后诞生,所以叫Parallel New。

Parallel Old是一个stop-the-world,基于压缩算法的多GC线程老年代垃圾收集器。

他和Paralledl Scavenge的区别是它做了增强使他可以和CMS配合使用。

CMS

Concurrent Mark Sweep

算法:三色标记 + Incremental Update

老年代

垃圾回收和应用程序同时运行,降低STW的时间(200ms)

CMS问题比较多,所以现在没有一个版本默认是CMS,只能手工指定

一个大多数并发、低停顿的收集器

CMS既然是MarkSweep,就一定会有碎片化的问题,碎片到达一定程度,CMS的老年代分配对象分配不下的时候,使用SerialOld 进行老年代回收

4阶段

初始标记 initial mark (STW)

并发标记 concurrent mark

重新标记 remark (STW)

并发清除 concurrent sweep

G1

算法:三色标记 + SATB(Snapshot-At-The-Beginnin)

Shenandoah

算法:ColoredPointers + WriteBarrier

Epsilon

Epsilon不回收内存,用来做测试的。

ZGC

算法:ColoredPointers + LoadBarrier

JVM指定垃圾收集器

-XX:+UseSerialGC = Serial New (DefNew) + Serial Old  

-XX:+UseParNewGC = ParNew + SerialOld(某些版本已废弃)

-XX:+UseConcMarkSweepGC = ParNew + CMS + Serial Old  

-XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默认)

-XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old  

-XX:+UseG1GC = G1
           

拓展阅读

《垃圾回收算法手册:自动内存管理的艺术》.https://book.douban.com/subject/26740958

《新一代垃圾回收器ZGC设计与实现》.https://book.douban.com/subject/34812818/