GC算法基础概念

GC算法的基础概念

Card Table

  • 由于做YGC时,需要扫描整个OLD区,效率非常低,所以JVM设计了CardTable
  • 如果一个OLD区CardTable中有对象指向Y区,就将它设为Dirty,下次扫描时,只需要扫描Dirty Card
  • 在结构上,Card Table用BitMap来实现

CMS

CMS的问题

Memory Fragmentation

  • -XX:+UseCMSCompactAtFullCollection
  • -XX:CMSFullGCsBeforeCompaction 默认为0 指的是经过多少次FGC才进行压缩

Floating Garbage

Concurrent Mode Failure

产生:

if the concurrent collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up,

or if an allocation cannot be satisfiedwith the available free space blocks in the tenured generation,

then theapplication is paused and the collection is completed with all the applicationthreads stopped

解决方案:降低触发CMS的阈值    

PromotionFailed

解决方案类似,保持老年代有足够的空间

  • –XX:CMSInitiatingOccupancyFraction 92% 可以降低这个值,让CMS保持老年代足够的空间

CMS日志分析

执行命令

java -Xms20M -Xmx20M -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC com.test.jvm.gc.T15_FullGC_Problem01
  • [GC (Allocation Failure)
  • [ParNew: 6144K->640K(6144K), 0.0265885 secs] 6585K->2770K(19840K), 0.0268035 secs]
  • [Times: user=0.02 sys=0.00, real=0.02 secs] 

ParNew:年轻代收集器

  • 6144->640:收集前后的对比
  • (6144):整个年轻代容量
  • 6585 -> 2770:整个堆的情况
  • (19840):整个堆大小
[GC (CMS Initial Mark) [1 CMS-initial-mark: 8511K(13696K)] 9866K(19840K), 0.0040321 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
    //8511 (13696) : 老年代使用(最大)
    //9866 (19840) : 整个堆使用(最大)
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.018/0.018 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
    //这里的时间意义不大,因为是并发执行
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    //标记Card为Dirty,也称为Card Marking
[GC (CMS Final Remark) [YG occupancy: 1597 K (6144 K)][Rescan (parallel) , 0.0008396 secs][weak refs processing, 0.0000138 secs][class unloading, 0.0005404 secs][scrub symbol table, 0.0006169 secs][scrub string table, 0.0004903 secs][1 CMS-remark: 8511K(13696K)] 10108K(19840K), 0.0039567 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    //STW阶段,YG occupancy:年轻代占用及容量
    //[Rescan (parallel):STW下的存活对象标记
    //weak refs processing: 弱引用处理
    //class unloading: 卸载用不到的class
    //scrub symbol(string) table: 
        //cleaning up symbol and string tables which hold class-level metadata and 
        //internalized string respectively
    //CMS-remark: 8511K(13696K): 阶段过后的老年代占用及容量
    //10108K(19840K): 阶段过后的堆占用及容量

[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.005/0.005 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
    //标记已经完成,进行并发清理
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    //重置内部结构,为下次GC做准备

1.6之前ps+po,1.6,1.7可以用cms,1.8及以后用G1

G1(JDK1.8版本开始成熟)

官方地址:https://www.oracle.com/technical-resources/articles/java/g1gc.html

G1日志详解

G1有一个参数,MaxGCPauseMillis -- 建议暂停时间

G1由各种region组成,为了达到建议暂停时间,G1会自动调整Y区大小,来接近这个建议值

使用G1GC

java -Xms20M -Xmx20M -XX:+PrintGCDetails -XX:+UseG1GC com.test.jvm.gc.T15_FullGC_Problem01

G1日志

  • G1的调整目标,尽量不要FGC
  • 正常情况下,不会FGC
  • 如果FGC时,Heap没怎么变化,一定有OOm
[GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0015790 secs]
//young -> 年轻代 Evacuation-> 复制存活对象 
//initial-mark 混合回收的阶段,这里是YGC混合老年代回收(mixedGC)
   [Parallel Time: 1.5 ms, GC Workers: 1] //一个GC线程
      [GC Worker Start (ms):  92635.7]
      [Ext Root Scanning (ms):  1.1]
      [Update RS (ms):  0.0]
         [Processed Buffers:  1]
      [Scan RS (ms):  0.0]
      [Code Root Scanning (ms):  0.0]
      [Object Copy (ms):  0.1]
      [Termination (ms):  0.0]
         [Termination Attempts:  1]
      [GC Worker Other (ms):  0.0]
      [GC Worker Total (ms):  1.2]
      [GC Worker End (ms):  92636.9]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.0 ms]
   [Other: 0.1 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.0 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.0 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 18.8M(20.0M)->18.8M(20.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
//以下是混合回收其他阶段
[GC concurrent-root-region-scan-start]
[GC concurrent-root-region-scan-end, 0.0000078 secs]
[GC concurrent-mark-start]
//无法evacuation,进行FGC
[Full GC (Allocation Failure)  18M->18M(20M), 0.0719656 secs]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 18.8M(20.0M)->18.8M(20.0M)], [Metaspace: 38
76K->3876K(1056768K)] [Times: user=0.07 sys=0.00, real=0.07 secs]
论读书
睁开眼,书在面前
闭上眼,书在心里
原文地址:https://www.cnblogs.com/YC-L/p/14422069.html