Full GC排查

感謝有奉獻精神的人

轉自:http://blog.csdn.net/huaweitman/article/details/50899839


我們的Java應用因頻繁FULL GC導致性能降低很多,經過多人的定位也沒有結論,於是我自主請命,經過一天的研究終於搞定了,現把經驗與大家共享,相關的gc日誌如下:

4.758: [Full GC [PSYoungGen: 464K->0K(71936K)] [PSOldGen: 37949K->33994K(68672K)] 38413K->33994K(140608K) [PSPermGen: 33221K->33221K(66560K)], 0.1887540 secs] [Times: user=0.20 sys=0.00, real=0.19 secs]

32.324: [Full GC [PSYoungGen: 12025K->0K(176320K)] [PSOldGen: 57570K->65642K(128256K)] 69595K->65642K(304576K) [PSPermGen: 35548K->35548K(76544K)], 0.2467320 secs] [Times: user=0.22 sys=0.02, real=0.25 secs]

50.133: [Full GC [PSYoungGen: 20999K->0K(437248K)] [PSOldGen: 118647K->114524K(198528K)] 139647K->114524K(635776K) [PSPermGen: 49637K->49637K(84224K)], 0.3302180 secs] [Times: user=0.32 sys=0.00, real=0.33 secs]

149.586: [Full GC [PSYoungGen: 44223K->0K(411712K)] [PSOldGen: 190278K->185382K(296064K)] 234501K->185382K(707776K) [PSPermGen: 50674K->50208K(85248K)], 0.6151800 secs] [Times: user=0.62 sys=0.00, real=0.61 secs]

260446.223: [Full GC [PSYoungGen: 31393K->0K(436032K)] [PSOldGen: 1006486K->396428K(1021312K)] 1037880K->396428K(1457344K) [PSPermGen: 61093K->61093K(61440K)], 1.3636610 secs] [Times: user=1.36 sys=0.00, real=1.52 secs]

260630.161: [Full GC (System) [PSYoungGen: 40410K->0K(424768K)] [PSOldGen: 991397K->721859K(1021312K)] 1031808K->721859K(1446080K) [PSPermGen: 61100K->61100K(61440K)], 2.1272130 secs] [Times: user=2.14 sys=0.00, real=2.13 secs]

260720.146: [Full GC (System) [PSYoungGen: 4949K->0K(439360K)] [PSOldGen: 1004066K->833610K(1021312K)] 1009015K->833610K(1460672K) [PSPermGen: 61108K->61108K(61440K)], 2.8408660 secs] [Times: user=2.72 sys=0.10, real=2.84 secs]

260810.150: [Full GC (System) [PSYoungGen: 33459K->0K(463552K)] [PSOldGen: 949989K->245655K(1021312K)] 983448K->245655K(1484864K) [PSPermGen: 61117K->61088K(61184K)], 1.1344010 secs] [Times: user=1.12 sys=0.02, real=1.14 secs]

03430.144: [Full GC (System) [PSYoungGen: 7390K->0K(489024K)] [PSOldGen: 871871K->393481K(976704K)] 879262K->393481K(1465728K) [PSPermGen: 64306K->64295K(64640K)], 1.3848850 secs] [Times: user=1.34 sys=0.06, real=1.38 secs]

403794.982: [Full GC [PSYoungGen: 9352K->0K(454144K)] [PSOldGen: 963758K->426051K(991744K)] 973110K->426051K(1445888K) [PSPermGen: 64298K->64298K(64640K)], 1.3783510 secs] [Times: user=1.32 sys=0.06, real=1.38 secs]

404120.149: [Full GC (System) [PSYoungGen: 6846K->0K(467648K)] [PSOldGen: 943642K->440168K(991744K)] 950489K->440168K(1459392K) [PSPermGen: 64300K->64300K(64640K)], 1.1605070 secs] [Times: user=1.12 sys=0.04, real=1.16 secs]

404466.698: [Full GC [PSYoungGen: 9719K->0K(472768K)] [PSOldGen: 980355K->442899K(1021312K)] 990074K->442899K(1494080K) [PSPermGen: 64303K->64303K(64640K)], 1.1729280 secs] [Times: user=1.14 sys=0.04, real=1.18 secs]

 

經過日誌分析,我找到兩個突破點,重點關注紅色字體部分的日誌,分析過程如下: 

1)FULL GC前後Java堆大小有變化;經研究發現是由於Java應用JVM參數XMS設置爲默認值,在我們的系統環境下,Hotspot的Xms默認值爲50M(-Xms默認是物理內存的1/64);每次GC時,JVM會根據各種條件調節Java堆的大小,Java堆的取值範圍爲[Xms, Xmx]。根據以上分析,修改Xms值與Xmx相等,這樣就不會因爲所使用的Java堆不夠用而進行調節,經過測試後發現FULL GC次數從四位數減少至個位數。


2)關鍵詞“System”讓我想到了System.gc調用,System.gc調用只是建議JVM執行年老代GC,而年老代GC觸發FULL GC,JVM會根據系統條件決定是否執行FULL GC,正因爲系統條件不好判斷,所以很難構造System.gc調用觸發FULL GC,幾經周折終於成功,當System.gc觸發FULL  GC時都會有關鍵詞“(System)”,而 JVM自動觸發的FULL GC卻不帶關鍵詞“(System)”,可以斷定是Java應用存在“System.gc”代碼。經過本次測試我也發現System.gc的真正含義,通俗言之,“System.gc” 就是FULL GC觸發的最後一根稻草。 

從本次分析中,我們可以得出如下的經驗: 
1)Java應用的jvm參數Xms與Xmx保持一致,避免因所使用的Java堆內存不夠導致頻繁full gc以及full gc中因動態調節Java堆大小而耗費延長其週期。 

2)建議不要調用System.gc或者Runtime.getRuntime().gc,否則本次調用可能會成爲“壓死駱駝的最後一根稻草”。當然我們可以通過設置jvm參數禁止這種調用生效,但是除非特別有把握該參數有必要添加,否則不推薦這麼設置。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章