一份很有意思的 GC log

weixin_34337265發表於2019-02-01
2405011-021bbe727dced4c1.png
GC log

這是 HBase 的 GC log。

遺憾由於沒有加 -XX:+PrintHeapAtGC 引數,日誌只有這些。

暴露的問題:

YGC 時間久,需要 3 至 5 秒,與出現問題之前的 20ms 有很大差距。

2405011-f53623aee3edbca4.png
YGC 時間久

JVM 配置如下:
堆大小 30G。
年輕代 3G,SurvivorRatio = 2,E 和 S 的大小分別為 1.5G 和 0.75G。


從日誌中可以推斷出,應該是 survivor 區空間少,導致存活物件超出 Desired survivor size = 0.75G * 50% = 402653184b,晉升閾值調整為 1,物件過早進入老年代導致。

圖中第一次 YGC 的時間為 20ms,比較正常。加了 PrintTenuringDistribution 引數,看到物件分佈。

從很多文章中寫到,PrintTenuringDistribution 列印的是 survivor 區的物件分佈。

但日誌中看到 812976448 total,約等於 775M,大於 survivor 區的 768M。

所以我將這個統計理解成希望進入 survivor to 區的物件分佈?

第一次正常 YGC 時,單是年齡為 1 的物件就超過了 survivor 區的大小。

所以 YGC 之後,survivor 區被年齡為 1 的物件填滿,並且由於 survivor 區的佔比超過了 50%,晉升閾值被調整為 1。在之後的 YGC 中,非新分配物件直接晉升到老年代。

在之後的 YGC 中,可以看到,每次 GC 之後,年輕代佔用的記憶體均為 786432K = 0.75G,恰好為一個 survivor 區的大小。

2405011-3b001ad9b981f991.png
之後 YGC 後的情況

認為之後新分配的存活物件在 YGC 後,佔滿了 survivor to 區。

但如果將 PrintTenuringDistribution 分佈理解成期望進入 survivor 區的物件分佈。

但是第一次異常 YGC 發生時,物件總數只用 773677304b 約等於 738M,不足以填滿 survivor 區的 768M。

2405011-de69d00ad5dff1d3.png
物件分佈

很是疑惑,求指點。

相關文章