JVM參數調優:Eclipse啓動實踐 html
本文主要參考自《深刻理解 Java 虛擬機》。 這本書是國人寫的可貴的不是照搬代碼註釋的且不是廢話連篇的技術書,內容涵蓋了 Java 從源碼到字節碼到執行的整個過程,包括了 JVM(Java Virtual Machine)的架構,垃圾收集的介紹等。這裏摘錄出關於配置 JVM 基本參數來調優 Eclipse 啓動的過程,比較初級,供初學者參考。 java
針對 JVM 的參數調優主要集中在數據區大小的控制和垃圾回收策略的選擇。關於 JVM 運行機制等更多內容可參考其餘博文 算法
運行時 JVM 的數據區主要包括各線程私有的棧和程序計數器,線程共享的方法區,以及管理對象的堆(又稱回收堆)等。程序運行時,類信息、常量、靜態變量等會被加載到方法區。運行過程當中幾乎全部對象都在堆裏,內存佔用的空間最大,這也是最值得優化得部分。 macos
Java 程序中,除了基本類型(primitive types),其餘的數據都是以對象的形式存在。對象生命週期有長有短,若是無區別的保留在內存中,會形成內存超載。內存垃圾回收(Garbage Collection, 縮寫 GC)就是解決這一問題的策略。 架構
注意:JVM 不只僅只對對象進行垃圾回收,實際上也會對廢棄常量和無用的類作回收。 oracle
垃圾回收首先得找到須要被回收的對象,通常採用根搜索算法來標記處這些過期的對象(另外有一種簡單的實現:引用計數,但存在明顯的弊端,即循環引用)。 app
回收垃圾的過程會消耗計算資源和時間。根據不一樣的處理方式,垃圾回收有不一樣的策略,如今經常使用的是分代收集算法:根據對象的存活週期將堆劃分爲幾代: 新生代(Young Generation 或 New Generation)和老生代(Tenured Generation),HotSpot 虛擬機裏還分出了永生代(基本等同於方法區)。不一樣代採用不一樣的垃圾回收策略。 eclipse
HotSpot 虛擬機中,Perm 代指永生代,Old 代指老年代,而新生代使用複製算法,將區域劃分爲三塊:Eden,S0 和 S1(S 是 Survivor 的縮寫)。 jvm
IBM 研究代表,新生代中的對象 98%是朝生夕死的,三者的比例劃分是 8:1:1。對象先分配到 Eden,若是 Eden 中內存佔用量達到必定得比例,觸發 Minor GC,JVM 會將 Eden 和 S0(或 S1)中存活的對象複製到 S1(或 S0),並清空 Eden 和 S0(或 S1)。若是同時老年代的內存佔用量打達到必定比例,會觸發 Major GC(也稱 Full GC)。一般 Major GC 比 Minor GC 慢 10 倍以上。 ide
Java 一直號稱「Write once, run anywhere」,這個特性正是由 JVM 這一虛擬層來支撐的。
Java 源代碼首先編譯爲 Java 字節碼,字節碼再被 JVM 加載運行。運行的過程能夠是直接針對字節碼的解釋執行,也能夠是通過了 JIT(Just in time)編譯爲機器碼後的執行。另外,還有靜態提早編譯器(Ahead Of Time,也縮寫爲 AOT),能將源碼直接編譯爲機器碼。
HotSpot 虛擬機的 JIT 編譯器有:Client Complier(簡稱 C1)、Server Complier(簡稱 C2)以及在 Java7 中堆出的分層編譯器。C1 編譯器作一些快速的優化,C2 作一些更耗時的優化可是產生更高效的代碼,而分層編譯器則結合了二者的優勢:快速的啓動和逐步的優化(brings client startup speeds to the server VM)。
對於系統調優和問題定位,周志明在《深刻 Java 虛擬機》中總結到
給一個系統定位問題的時候,知識、經驗是關鍵基礎,數據是依據,工具是運用知識處理數據的手段。這裏說的數據包括:運行日誌、異常堆棧、GC 日誌、線程快照、堆轉儲快照等……應當意識到工具永遠都是知識技能的一層包裝,沒有什麼工具是「祕密武器」。
Java 提供了不少工具給開發者來監控和處理運行中的問題。包括命令行工具以及可視化工具
好比 jps, jstat, jinfo 等。舉例以下:
1 2 3 |
jstat -gcutil xxx #xxx 是 jps 查出的 LVMID,查看 gc 相關數據 jstat -gccause xxx#查看 gc 的緣由 jinfo -flag XXX xxx#XXX 是參數名,xxx 是 VMID,查看虛擬機的參數值 |
這裏零散的羅列了一些我用到的簡單的 JVM 配置參數:
內存大小控制:
編譯相關:
其餘:
調優 Eclipse 啓動實際上就是調優 Eclipse 在 JVM 中的加載和程序啓動階段的運行。因爲默認的 Ecpise 啓動配置沒法適應全部不一樣的硬件、軟件環境,作針對性的調優是必要的。
Eclipse 的啓動配置文件是 eclipse.ini,對 JVM 的參數調優直接在該文件中修改。OS X 下,其文件路徑爲 $ECLIPSE/Eclipse.app/Contents/MacOS/eclipse.ini(注意不是 Eclipse 文件包根目錄下得 eclipse.ini)。
要優化 Eclipse 的啓動時間,先要能肯定 Eclipse 的啓動時間。這裏推薦網友實現的一個 Eclipse 插件:計算啓動時間的 Eclipse 插件。下載後放到 Eclipse 的插件包中,啓動 Eclipse 便可看到彈窗顯示的啓動時間。爲了獲得一個儘量公平的測試結果,須要在測試過程當中關閉其餘程序,避免 CPU 負載帶來的偏差,並屢次測試取平均值。
使用 VisualVM 查看程序的運行情況來定位瓶頸,嘗試調優解決。下圖是 VisualVM 的示例圖,右邊圖示展現了 GC 的狀態以及編譯時間、類加載時間和垃圾回收時間等指標。
也能夠經過命令行工具查看 GC 的狀態,好比:jstat -gc XXX #其中 XXX 是 jps 查出的進程的 LVMID.
個人實踐總結以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
-startup ../../../plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar --launcher.library ../../../plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.200.v20130807-1835 -product org.eclipse.epp.package.standard.product --launcher.defaultAction openFile -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m --launcher.defaultAction openFile --launcher.appendVmargs -vmargs -Dosgi.requiredJavaVersion=1.6 -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -Xms1024m -Xmx1024m -Xmn800m -Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -XX:+TieredCompilation -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -XVerify:none -XX:+UseParNewGC -XX:+UserConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 |