JVM垃圾回收

2021.02.10 15:02 732
阅读约 9 分钟

垃圾回收算法

标记清除算法

通过GC Root 可达性分析算法可以对堆中的对象进行分析,对不可达对象进行标记,并且在下次垃圾回收时回收这些对象,其缺点是不能对内存碎片进行整理,优点是回收速度快。

标记整理算法

通过可达性分析算法从GC Root出发对堆中所有对象的可达性进行分析,对于不可达的对象进行标记,在下次垃圾回收时回收这些对象,并同时整理内存碎片,缺点是内存整理比较耗时,因此性能要差于标记清除算法。

复制算法

从堆中划分出两个区域,FROM与TO,在垃圾回收时,将存活的对象复制到TO区域,并清除FROM区域的对象。同时将FROM区域与原来的TO区域交换(TO区域始终为空)。

分代垃圾回收

  • 对象首先分配在Eden区中
  • 新生代空间不足时,触发minor GC,Eden区与幸存区From中的引用可达的对象会被转移到幸存区To中,对象的年龄加1,并且交换From与To区域。
  • minor GC 会引发著名的 stop the world,暂停其它线程,等垃圾回收结束后,才会恢复用户线程。
  • 当新生代中对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)
  • 当老年代空间不足时,会先触发minor GC,如果空间仍不足,会触发FullGC,STW时间更长。

 

相关vm参数

堆初始大小: -Xms 

堆最大大小:-Xmx 或 -XX:MaxHeapSize=size 

新生代大小: -Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size ) 

幸存区比例:(动态) -XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy 

幸存区比例: -XX:SurvivorRatio=ratio 

晋升阈值: -XX:MaxTenuringThreshold=threshold 

晋升详情: -XX:+PrintTenuringDistribution 

GC详情: -XX:+PrintGCDetails -verbose:gc 

FullGC 前 MinorGC: -XX:+ScavengeBeforeFullGC

垃圾回收器

串行

-XX:+UseSerialGC = Serial + SerialOld

吞吐量优先 

-XX:+UseParallelGC ~ -XX:+UseParallelOldGC 

-XX:GCTimeRatio=ratio 

-XX:MaxGCPauseMillis=ms 

-XX:ParallelGCThreads=n

响应时间优先(cms回收器)

基于标记清除算法,用户线程与垃圾回收线程并发运行。

-XX:+UseConcMarkSweepGC ~ -XX:+UseParNewGC ~ SerialOld 

-XX:ParallelGCThreads=n ~ -XX:ConcGCThreads=threads 

-XX:CMSInitiatingOccupancyFraction=percent 

-XX:+CMSScavengeBeforeRemark

初始标记非常快,同时垃圾回收线程也可以进行并发的标记,但是还要在做一遍重新标记的工作,并在之后并发回收垃圾。

G1(Garbage First)

适用场景 

同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是 200 ms 

超大堆内存,会将堆划分为多个大小相等的 Region 

整体上是 标记+整理 算法,两个区域之间是 复制 算法 

相关 JVM 参数 

-XX:+UseG1GC 

-XX:G1HeapRegionSize=size 

-XX:MaxGCPauseMillis=time

垃圾回收阶段

Young Collection(新生代垃圾回收)

会STW

工作一段时间后,会将GC Root可达的对象放入幸存区,

幸存区还存活的对象的会晋升到老年区

Young Collection + CM

在 Young GC 时会进行 GC Root 的初始标记 

老年代占用堆空间比例达到阈值时,进行并发标记(不会 STW),由下面的 JVM 参数决定

-XX:InitiatingHeapOccupancyPercent=percent (默认45%)

Mixed Collection

会对 E、S、O 进行全面垃圾回收 

最终标记(Remark)会 STW 

拷贝存活(Evacuation)会 STW 

-XX:MaxGCPauseMillis=ms 

Full GC 

  • SerialGC
    • 新生代内存不足发生的垃圾收集 - minor gc
    • 老年代内存不足发生的垃圾收集 - full gc
  • ParallelGC
    • 新生代内存不足发生的垃圾收集 - minor gc
    • 老年代内存不足发生的垃圾收集 - full gc
  • CMS
    • 新生代内存不足发生的垃圾收集 - minor gc
    • 老年代内存不足
  • G1
    • 新生代内存不足发生的垃圾收集 - minor gc
    • 老年代内存不足

Young Collection 跨代引用

新生代回收的跨代引用(老年代引用新生代)问题

卡表与 Remembered Set 

在引用变更时通过 post-write barrier + dirty card queue 

concurrent refinement threads 更新 Remembered Set

重标记 Remark 

pre-write barrier + satb_mark_queue

如何优化 JVM 频繁 minor GC

 

 

 

字数:2239 发布于 10 个月前
Copyright 2018-2021 Siques