JVM的GC日誌

煲煲菜發表於2018-11-12

通過-XX:+PrintGC-XX:+PringGCDetails引數可以列印出簡略的或詳細的GC日誌。

JVM的GC有兩種:Minor GCFull GC

Minor GC日誌: 一個示例:

[GC [PSYoungGen: 3264K->0K(3328K)] 3576K->312K(10176K), 0.0001356 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
複製程式碼

我覺得吧,把日誌縮排顯示容易看一點:

[GC                             // 表示是minor GC,即對新生代進行垃圾回收
    [PSYoungGen:                // PS:垃圾回收器,Parallel Scavenge;YoungGen:新生代
        3264K->0K(3328K)        // 新生代記憶體變化情況。gc前->gc後(總記憶體)
    ] 
    3576K->312K(10176K),        // 堆記憶體變化情況。gc前->gc後(總記憶體)
    0.0001356 secs              // 新生代垃圾回收耗時
] 
[Times: 
    user=0.00                   // 使用者耗時
    sys=0.00,                   // 系統耗時
    real=0.00 secs              // 實際耗時
]
複製程式碼

上面的PSYoungGen可以看出垃圾回收發生在新生代的,用的是Parallel GC垃圾回收器,相關引數:-XX:+UseParallelGC

Full GC日誌: 一個示例:

[Full GC (Metadata GC Threshold) [PSYoungGen: 7677K->0K(103936K)] [ParOldGen: 5847K->13176K(71168K)] 13525K->13176K(175104K), [Metaspace: 20580K->20580K(1067008K)], 0.0551431 secs] [Times: user=0.14 sys=0.00, real=0.05 secs] 
複製程式碼

縮排:

[Full GC (Metadata GC Threshold)    // Full GC(gc的原因,由於Metaspace區域記憶體達到了閾值觸發full gc)
    [PSYoungGen:                    // 新生代GC
        7677K->0K(103936K)          // 新生代記憶體變化情況。gc前->gc後(總記憶體),減少7677K
    ] 
    [ParOldGen:                     // 老年代GC
        5847K->13176K(71168K)       // 老年代記憶體變化情況。gc前->gc後(總記憶體),增加7329K
    ] 
    13525K->13176K(175104K),        // 堆記憶體變化情況。gc前->gc後(總記憶體),
                                    // 13525-13176=減少了349K,而上面-7677+7329=減少了348K,資料基本吻合
    
    [Metaspace: 
        20580K->20580K(1067008K)    // 後設資料區記憶體變化情況。gc前->gc後(總記憶體),
    ], 0.0551431 secs               // 整個GC過程耗時
] 
[Times: user=0.14 sys=0.00, real=0.05 secs] 
複製程式碼

上面的ParOldGen可以看出垃圾回收發生在老年代的,用的是一個並行的標記清除壓縮垃圾回收器

參考:

ParOldGen – Type of the collector used to clean the Old Generation. In this case, parallel mark-sweep-compact stop-the-world garbage collector named ParOldGen was used.

關於Metaspace的初始大小請看這裡

By default class metadata allocation is only limited by the amount of available native memory. We can use the new option MaxMetaspaceSize to limit the amount of native memory used for the class metadata. It is analogous to MaxPermSize. A garbage collection is induced to collect the dead classloaders and classes when the class metadata usage reaches MetaspaceSize (12Mbytes on the 32bit client VM and 16Mbytes on the 32bit server VM with larger sizes on the 64bit VMs). Set MetaspaceSize to a higher value to delay the induced garbage collections. After an induced garbage collection, the class metadata usage needed to induce the next garbage collection may be increased.

Full GC還會在程式退出前列印下面的資訊:

Heap
 PSYoungGen      total 3328K, used 69K [0x000000000b580000, 0x000000000b8d0000, 0x000000000b8d0000) //Line1
  eden space 3264K, 2% used [0x000000000b580000,0x000000000b591688,0x000000000b8b0000)
  from space 64K, 0% used [0x000000000b8b0000,0x000000000b8b0000,0x000000000b8c0000)
  to   space 64K, 0% used [0x000000000b8c0000,0x000000000b8c0000,0x000000000b8d0000)
 PSOldGen        total 6848K, used 312K [0x000000000aed0000, 0x000000000b580000, 0x000000000b580000) //Line2
  object space 6848K, 4% used [0x000000000aed0000,0x000000000af1e0c0,0x000000000b580000)
 PSPermGen       total 21248K, used 3817K [0x0000000005ad0000, 0x0000000006f90000, 0x000000000aed0000) //Line3 
  object space 21248K, 17% used [0x0000000005ad0000,0x0000000005e8a4a0,0x0000000006f90000)
複製程式碼

Line1解析:

 PSYoungGen                 //新生代 
    total 3328K,            //總大小
    used 69K                //已使用
    [0x000000000b580000,    //16進位制數,表示新生代下界
    0x000000000b8d0000,     //新生代當前上屆
    0x000000000b8d0000)     //新生代上屆
複製程式碼
新生代空間最大值 = 上界 - 下界  = 0x000000000b8d0000 - 0x000000000b580000 
                            = 350000(16進位制) 
                            = 3473408(10進位制)
                            = 3473408 / 1024 = 3392K
3392K剛好等於下面 eden + from + to的大小。

當前已分配的新生代空間大小 = 當前上界 - 下界 = 3392K
複製程式碼

Line2: 老年代的記憶體情況

Line3: 永久代的記憶體情況

參考文章: GC日誌分析

相關文章