1. 程式人生 > >Java 應用 頻繁 FullGC 分析

Java 應用 頻繁 FullGC 分析

一、JVM的記憶體分佈

1.1 JVM記憶體分佈概況

img

  • 堆記憶體劃分為: Eden、Survivor 和 Tenured/Old 空間
    img

1.2 Minor GC、Major GC、Full GC

1.3 JVM垃圾回收演算法

img

二、應用的GC日誌配置

2.1 應用GC日誌配置

JVM的GC日誌的主要引數包括如下幾個:

-XX:+PrintGC 輸出GC日誌
-verbose:gc 示輸出虛擬機器中GC的詳細情況
-XX:+PrintGCDetails 輸出GC的詳細日誌
-XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行GC的前後打印出堆的資訊
-Xloggc:../logs/gc.log 日誌檔案的輸出路徑

-verbose:gc 中引數-verbose:gc 表示輸出虛擬機器中GC的詳細情況.

使用後輸出如下:

[Full GC 168K->97K(1984K), 0.0253873 secs]

解讀如下:

  箭頭前後的資料168K和97K分別表示垃圾收集GC前後所有存活物件使用的記憶體容量,說明有168K-97K=71K的物件容量被回收,括號內的資料1984K為堆記憶體的總容量,收集所需要的時間是0.0253873秒(這個時間在每次執行的時候會有所不同)

2.2 線上應用配置例項

img

2.2 應用GC日誌分析

2017-06-02T15:10:11.930+0800: 68752.147: [GC2017-06-02T15:10:11.930+0800: 68752.147: [ParNew: 1679677K->1878K(1887488K), 0.0176620 secs] 2204253K->526489K(6753536K), 0.0178770 secs] [Times: user=0.07 sys=0.00, real=0.02 secs]
2017-06-02T15:10:18.522+0800: 68758.739: [GC2017-06-02T15:10:18.522+0800: 68758.739: [ParNew: 1679702K->2122K(1887488K), 0.0184380 secs] 2204313K->526767K(6753536K), 0.0186610 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
2017-06-02T15:10:22.812+0800: 68763.029: [GC2017-06-02T15:10:22.812+0800: 68763.030: [ParNew: 1679946K->2104K(1887488K), 0.0166490 secs] 2204591K->526796K(6753536K), 0.0168640 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
2017-06-02T15:10:29.874+0800: 68770.091: [GC2017-06-02T15:10:29.874+0800: 68770.091: [ParNew: 1679928K->1646K(1887488K), 0.0174360 secs] 2204620K->526439K(6753536K), 0.0176530 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]

取倒數第一條記錄分析一下各個欄位都代表了什麼含義

2017-06-02T15:10:29.874+0800: 68770.091: (時間)[GC(Young GC)2017-06-02T15:10:29.874+0800: 68770.091: [ParNew()使用ParNew作為年輕代的垃圾回收): 1679928K(年輕代垃圾回收前的大小)->1646K年輕代垃圾回收以後的大小)(1887488K)(年輕代的總大小), 0.0174360 secs(回收時間)]] 2204620K(堆區垃圾回收前的大小)->526439K(堆區垃圾回收後的大小)(6753536K(堆區總大小), 0.0176530 secs(回收時間)] [Times: user=0.06Young GC使用者耗時) sys=0.00(Young GC系統耗時), real=0.02 secsYoung GC實際耗時)]

我們再對資料做一個簡單的分析:

從最後一條GC記錄中我們可以看到 Young GC回收了 1679928-1646=1678282K的記憶體
Heap區通過這次回收總共減少了 2204620-526439=1678181K的記憶體。

1678282-1678181=101K說明通過該次Young GC有101K的記憶體被移動到了Old Gen

我們來驗證一下

在最後一次Young GC的回收以前 Old Gen的大小為526796(倒數第二條堆記憶體)-2104=524692 <br/>
回收以後Old Gen的記憶體使用為526439-1646=524793
Old Gen在該次Young GC以後記憶體增加了524793-524692=10K 與預計的相符

三、常見GC檢視工具

img