JVM 調優之 Eclipse 啟動調優實戰

本文是我12年在學習《深入理解Java虛擬機:JVM高級特性與最佳實踐》時,做的一個 JVM 簡單調優實戰筆記,版本都有些過時,不過調優思路和過程還是可以分享給大家參考的。

環境基礎配置

硬件: Dell E5410, Intel i3 CPU M 370, 2GB內存
系統: 32位 Windows XP
虛擬機: Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)
Eclipse版本: Release 4.2.0 Last revised June 8th, 2012

調優前

Eclipse初始配置文件

eclipse.ini

<code>-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120522-1813
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs

-Dosgi.requiredJavaVersion=1.5
-Dhelp.lucene.tokenizer=standard
-Xms40m
-Xmx512m
/<code>

調優前的測試結果

  • 平均耗時約: 10 秒
  • 垃圾收集器總耗時 1.710 s,其中:Full GC被觸發了 8 次,耗時 1.438 s;Minor GC被觸發了 29 次,耗時 272.185 ms;Eclipse 運行一段時間後,會顯式的調用 System.gc() 方法做 Full GC。
  • 加載類:8279 個,耗時 7.598 s
  • JIT的編譯時間為: 1.829 s
  • 虛擬機 512MB 的內存被分配為 170MB 的新生代(Eden 區為 136MB 和兩個 17MB的Survivor 區)和 342MB 的老年代


JVM 調優之 Eclipse 啟動調優實戰


Eclipse啟動過程:

JVM 調優之 Eclipse 啟動調優實戰


Eclipse啟動後,運行一段時間:

JVM 調優之 Eclipse 啟動調優實戰

分析及調優

升級JDK版本

獲取免費的“性能提升”(這裡暫時不做考慮)。

類加載和編譯時間優化

類加載: 字節碼驗證優化。 考慮到實際情況: Eclipse 使用者甚多,它的編譯代碼是可靠的,不需要在加載的時候再進行字節碼驗證。
優化措施: 添加參數 -Xverify:none,禁止字節碼驗證。
編譯時間:

調整內存設置控制垃圾收集頻率

第一次

新生代 Minor GC 的發生是因為分配給新生代的空間太小導致的。
Full GC產生的原因,從GC日誌中分析:

<code>2.558: [Full GC 2.558: [Tenured: 5029K->6089K(27328K), 0.0769168 secs] 7919K->6089K(39616K), [Perm : 16383K->16383K(16384K)], 0.0769992 secs] [Times: user=0.08 sys=0.00, real=0.08 secs]
4.740: [Full GC 4.740: [Tenured: 9085K->11372K(27328K), 0.1007947 secs] 13555K->11372K(39680K), [Perm : 20479K->20479K(20480K)], 0.1008572 secs] [Times: user=0.08 sys=0.00, real=0.09 secs]
5.853: [Full GC 5.853: [Tenured: 13120K->16847K(27328K), 0.1368830 secs] 25460K->16847K(39680K), [Perm : 24575K->24575K(24576K)], 0.1369769 secs] [Times: user=0.14 sys=0.00, real=0.14 secs]
6.317: [Full GC 6.317: [Tenured: 16847K->17236K(28080K), 0.1789713 secs] 20615K->17236K(40752K), [Perm : 28671K->28646K(28672K)], 0.1791253 secs] [Times: user=0.17 sys=0.00, real=0.17 secs]
7.247: [Full GC 7.248: [Tenured: 19043K->20238K(28728K), 0.1739436 secs] 20408K->20238K(41720K), [Perm : 32767K->32767K(32768K)], 0.1740637 secs] [Times: user=0.17 sys=0.00, real=0.17 secs]
7.928: [Full GC 7.928: [Tenured: 20238K->22897K(33732K), 0.2087824 secs] 31501K->22897K(48964K), [Perm : 36863K->36863K(36864K)], 0.2093529 secs] [Times: user=0.20 sys=0.00, real=0.20 secs]
9.892: [Full GC 9.892: [Tenured: 22897K->25238K(38164K), 0.2628295 secs] 38655K->25238K(55444K), [Perm : 40959K->40959K(40960K)], 0.2629460 secs] [Times: user=0.27 sys=0.00, real=0.27 secs]
/<code>

日誌打印參數

<code>-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:gc.log
/<code>

從上面可以看出來,7 次 Full GC 中,最後 4 次 Full GC 是為了老年代擴容,從 27328K 擴容到最後 38164K 。從數據中,可以看出前 3 次的 Full GC 是為了永久代的擴容而觸發的。


由上述分析可以得出結論
Eclipse 啟動的時候,Full GC 大多數是由於老年代和永久代容量擴展而導致的,為了避免性能浪費,可以把 -Xms 和 -XX:PermSize 參數值分別設置為 -Xmx 和 -XX:PermSizeMax 參數值,即大小設置一致,減少自動擴容。

優化具體措施
新生代設置為 170MB,避免新生代頻繁 GC 做擴容:
把 Java 堆、永久代的容量分別固定為 512MB 和 256MB,避免內存擴展。

調整後的eclipse.ini內容

<code>-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library

plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120522-1813
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Dhelp.lucene.tokenizer=standard
-Xverify:none
-Xms512m
-Xmx512m
-Xmn170m
-XX:PermSize=256m
/<code>

第二次

調優後運行結果,再次分析:


JVM 調優之 Eclipse 啟動調優實戰


JVM 調優之 Eclipse 啟動調優實戰


JVM 調優之 Eclipse 啟動調優實戰


從 Old Gen 曲線上看,老年代直接固定在 342MB,使用 25.69MB,並且一直很平滑,完全不應該發生 Full GC 才對。再從 GC 日誌看,發現 Full GC 後面標記了一個 System,而圖中GC time 的 Last Cause:System.gc() 為,說明系統顯式的調用了 System.gc()。

優化措施:
去除顯式的調用 System.gc() ,添加參數-XX:+DisableExplicitGC屏蔽掉 System.gc().

調整後的eclipse.ini內容:

<code>-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120522-1813
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Dhelp.lucene.tokenizer=standard
-Xverify:none
-Xms512m
-Xmx512m
-Xmn170m
-XX:PermSize=256m
-XX:+DisableExplicitGC

/<code>

調優後

類加載優化結果

添加參數-Xverify:none後,類加載時間從 7.598s 減少到 4.665s。


JVM 調優之 Eclipse 啟動調優實戰

JVM 調優之 Eclipse 啟動調優實戰


調整內存設置控制後結果

第一次:

JVM 調優之 Eclipse 啟動調優實戰


JVM 調優之 Eclipse 啟動調優實戰


JVM 調優之 Eclipse 啟動調優實戰


GC日誌:

<code>2.845: [GC 2.846: [DefNew: 139264K->7351K(156672K), 0.0463358 secs] 139264K->7351K(506880K), 0.0463981 secs] [Times: user=0.05 sys=0.00, real=0.05 secs]
4.581: [GC 4.582: [DefNew: 146615K->16818K(156672K), 0.0786477 secs] 146615K->16818K(506880K), 0.0787217 secs] [Times: user=0.08 sys=0.00, real=0.08 secs]
64.279: [Full GC (System) 64.279: [Tenured: 0K->26315K(350208K), 0.3266376 secs] 127364K->26315K(506880K), [Perm : 39195K->39195K(262144K)], 0.3267561 secs] [Times: user=0.31 sys=0.01, real=0.33 secs]
/<code>

在調整後的參數設置下, GC 次數已經大幅度減少。上圖是 Eclipse 啟動後 1 分鐘的監視曲線,只發生了 2 次 Minor GC 和 1 次 Full GC,總耗時 451.603ms。相比之前的1.710s,減少了 2 倍多.

第二次:

JVM 調優之 Eclipse 啟動調優實戰


已經完全沒有 Full GC 了。

總結

以上只是專門針對 Eclipse 的啟動過程進行分析和調優,並未對 Eclipse 日常開發工作進行分析和調優。

  • 《深入理解Java虛擬機:JVM高級特性與最佳實踐》


分享到:


相關文章: