GC調優是個很實驗很伽利略的活兒,GC日誌是先決的數據參考和最終驗證:html
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps(GC發生的時間) -XX:+PrintGCApplicationStoppedTime(GC消耗了多少時間) -XX:+PrintGCApplicationConcurrentTime(GC之間運行了多少時間)
配置參數:-XX:+UseConcMarkSweepGC
已默認無需配置的參數:-XX:+UseParNewGC(Parallel收集新生代) -XX:+CMSPermGenSweepingEnabled(CMS收集持久代) -XX:UseCMSCompactAtFullCollection(full gc時壓縮年老代)java
初始效果:1g堆內存的新生代約60m,minor gc約5-20毫秒,full gc約130毫秒。工具
配置參數: -XX:+UseParallelGC -XX:+UseParallelOldGC(Parallel收集年老代,從JDK6.0開始支持)性能
已默認無需配置的參數: -XX:+UseAdaptiveSizePolicy(動態調整新生代大小)測試
初始效果:1g堆內存的新生代約90-110m(動態調整),minor gc約5-20毫秒,full gc有無UseParallelOldGC 參數分別爲1.3/1.1秒,差異不大。優化
另外-XX:MaxGCPauseMillis=100 設置minor gc的指望最大時間,JVM會以此來調整新生代的大小,但在此測試環境中對象死的太快,此參數做用不大。spa
Parallel收集高達1秒的暫停時間基本不可忍受,因此選擇CMS收集器。線程
在被壓測的Mule 2.0應用裏,每秒都有大約400M的海量短命對象產生:日誌
對這兩個參數的調優,既要改善上面兩種狀況,又要避免新生代過大,複製次數過多形成minor gc的暫停時間過長。code
優化後,大約1.1秒才發生一次minor gc,且速度依然保持在15-20ms之間。同時年老代的增加速度大大減緩,好久才發生一次full gc,
參數定稿:
-server -Xms1024m -Xmx1024m -Xmn500m -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=5 -XX:+ExplicitGCInvokesConcurrent
最後服務處理速度從1180 tps 上升到1380 tps,調整兩個參數提高17%的性能仍是筆很划算的買賣。
另外,JDK6 Update 7自帶了一個VisualVM工具,內裏就是以前也有用過的Netbean Profiler,相似JConsole同樣使用,能夠看到線程狀態,內存中對象以及方法的CPU時間等調優重要參考依據。免費捆綁啊,Sun 這樣搞法,其餘作Profiler的公司要關門了。
(源自:http://calvin.iteye.com/blog/212967)