監(jiān)控:
1焰坪,minor GC和full GC的頻率趣倾;
2,執(zhí)行一次GC所消耗的時間某饰;
3儒恋,新生代的對象何時被移到老生代以及花費了多少時間;
4黔漂,每次GC中诫尽,其它線程暫停(Stop the world)的時間;
5炬守,每次GC的效果如何牧嫉,是否不理想;
調(diào)優(yōu)方法:
一切都是為了這一步减途,調(diào)優(yōu)酣藻,在調(diào)優(yōu)之前,我們需要記住下面的原則:
多數(shù)的Java應用不需要在服務器上進行GC優(yōu)化观蜗;
多數(shù)導致GC問題的Java應用臊恋,都不是因為我們參數(shù)設置錯誤,而是代碼問題墓捻;
在應用上線之前,先考慮將機器的JVM參數(shù)設置到最優(yōu)(最適合);
減少創(chuàng)建對象的數(shù)量砖第;
減少使用全局變量和大對象撤卢;
GC優(yōu)化是到最后不得已才采用的手段;
在實際使用中梧兼,分析GC情況優(yōu)化代碼比優(yōu)化GC參數(shù)要多得多放吩;
GC優(yōu)化的目的有兩個(http://www.360doc.com/content/13/0305/10/15643_269388816.shtml):
將轉移到老年代的對象數(shù)量降低到最小羽杰;
減少full GC的執(zhí)行時間渡紫;
為了達到上面的目的,一般地考赛,你需要做的事情有:
減少使用全局變量和大對象惕澎;
調(diào)整新生代的大小到最合適;
設置老年代的大小為最合適颜骤;
選擇合適的GC收集器唧喉;
在上面的4條方法中,用了幾個“合適”忍抽,那究竟什么才算合適八孝,一般的,請參考上面“收集器搭配”和“啟動內(nèi)存分配”兩節(jié)中的建議鸠项。但這些建議不是萬能的干跛,需要根據(jù)您的機器和應用情況進行發(fā)展和變化,實際操作中祟绊,可以將兩臺機器分別設置成不同的GC參數(shù)驯鳖,并且進行對比,選用那些確實提高了性能或減少了GC時間的參數(shù)久免。
真正熟練的使用GC調(diào)優(yōu)浅辙,是建立在多次進行GC監(jiān)控和調(diào)優(yōu)的實戰(zhàn)經(jīng)驗上的,進行監(jiān)控和調(diào)優(yōu)的一般步驟為:
1阎姥,監(jiān)控GC的狀態(tài)
使用各種JVM工具记舆,查看當前日志,分析當前JVM參數(shù)設置呼巴,并且分析當前堆內(nèi)存快照和gc日志泽腮,根據(jù)實際的各區(qū)域內(nèi)存劃分和GC執(zhí)行時間,覺得是否進行優(yōu)化衣赶;
2诊赊,分析結果,判斷是否需要優(yōu)化
如果各項參數(shù)設置合理府瞄,系統(tǒng)沒有超時日志出現(xiàn)碧磅,GC頻率不高,GC耗時不高,那么沒有必要進行GC優(yōu)化鲸郊;如果GC時間超過1-3秒丰榴,或者頻繁GC,則必須優(yōu)化秆撮;
注:如果滿足下面的指標四濒,則一般不需要進行GC:
Minor GC執(zhí)行時間不到50ms;
Minor GC執(zhí)行不頻繁职辨,約10秒一次盗蟆;
Full GC執(zhí)行時間不到1s;
Full GC執(zhí)行頻率不算頻繁舒裤,不低于10分鐘1次喳资;
3,調(diào)整GC類型和內(nèi)存分配
如果內(nèi)存分配過大或過小惭每,或者采用的GC收集器比較慢骨饿,則應該優(yōu)先調(diào)整這些參數(shù),并且先找1臺或幾臺機器進行beta台腥,然后比較優(yōu)化過的機器和沒有優(yōu)化的機器的性能對比宏赘,并有針對性的做出最后選擇;
4黎侈,不斷的分析和調(diào)整
通過不斷的試驗和試錯察署,分析并找到最合適的參數(shù)
5,全面應用參數(shù)
如果找到了最合適的參數(shù)峻汉,則將這些參數(shù)應用到所有服務器贴汪,并進行后續(xù)跟蹤。
JVM日志參數(shù):
-Xloggc:path/to/gc.log: 啟用GC日志休吠,并指定日志文件路徑和名稱扳埂。例如:-Xloggc:/var/log/gc.log。
-verbose:gc: 打印簡略的GC信息瘤礁,包含GC時間和GC后內(nèi)存的占用情況阳懂。
-XX:+PrintGCDetails: 打印詳細的GC信息,包含GC時間柜思、GC前后內(nèi)存的占用情況岩调、對象分配數(shù)量、回收類型等赡盘。
-XX:+PrintGCDateStamps: 在詳細GC信息中打印時間戳号枕。
-XX:+PrintHeapAtGC: 在GC之后打印堆的詳細使用情況。
-XX:+PrintTenuringDistribution: 打印關于年齡分布的詳細信息陨享,這個參數(shù)主要用于調(diào)試新生代GC過程葱淳。
-XX:+PrintCommandLineFlags: 在JVM啟動時打印出所有的命令行參數(shù)及其默認值钝腺。
-XX:+PrintStringTableStatistics: 打印字符串常量池相關信息。
-XX:+PrintCompilation: 打印JIT編譯器編譯代碼的詳細信息蛙紫,用于調(diào)試JIT編譯器拍屑。
-XX:+PrintClassHistogram: 打印Java堆中每個類的實例數(shù)量和占用空間情況途戒。
除了上述參數(shù)坑傅,還可以通過配置不同的日志級別來打印更加詳細或者簡略的JVM日志信息。例如:-XX:ErrorFile=/var/log/jvm_error.log喷斋,可以指定錯誤日志的輸出位置唁毒。尤其在生產(chǎn)環(huán)境下,JVM日志對于故障排查和優(yōu)化調(diào)優(yōu)都非常重要星爪,建議對JVM日志進行充分配置和記錄浆西。