有用的幾個JVM參數

  JVM是多數開發人員視爲理所固然的 Java功能和性能背後的重負荷機器,然而,咱們不多有人能理解JVM是如何進行 工做的—像任務分配和垃圾收集、轉動線程、打開和關閉文件、中斷和/或JIT編譯Java字節碼,等等。

  不熟悉JVM將不只會影響應用程序性能,並且當JVM出問題時,嘗試修復也會很困難。 html

  本文將介紹一些命令行標誌,您可使用它們來診斷和調優您的Java虛擬機性能。 java

  1.DisableExplicitGC 安全

  我已記不清有多少次用戶要求我就應用程序性能問題提供諮詢了,其實只要跨代碼快速運行grep,就會發現清單1所示的問題—原始Java性能反模式: 服務器

  清單 1. System.gc(); 工具

// We just released a bunch of objects, so tell the stupid 
// garbage collector to collect them already! 
System.gc(); 

 顯式垃圾收集是一個很是糟糕的主意——就像將您和一個瘋狂的鬥牛犬鎖在一個電話亭裏。儘管調用的語法是依賴實現的,但若是您的JVM正在運行一個分代的 垃圾回收器(大多數是)System.gc();強迫VM執行一個堆的「所有清掃」,雖然有的沒有必要。所有清掃比一個常規GC操做要昂貴好幾個數量級, 這只是個簡單數學問題。 性能

  您能夠不把個人話放在心上—Sun的工程師爲這個特殊的人工錯誤提供一個JVM標 志;-XX:+DisableExplicitGC標誌自動將System.gc()調用轉換成一個空操做,爲您提供運行代碼的機會,您本身看看 System.gc()對於整個JVM執行有害仍是有利。 測試

  2.HeapDumpOnOutOfMemoryError spa

  您有沒有經歷過這樣的狀況:JVM不能使用,不斷拋出OutOfMemoryError,而您又不能爲本身建立調試器來捕獲它或查看出現了什麼問題?像這類偶發和/或不肯定的問題,一般使開發人員發瘋。 命令行

  買者自負 線程

 並非任何VM都支持全部命令行標誌,Sun/Oracle的VM除外。查明一個標誌是否被支持的最好方法是試用它,看它是否正常工做。假若這些標誌在 技術上是不支持的,那麼,使用它們您要承擔所有責任。若是這些標誌中的任何一個使您的代碼、您的數據、您的服務器或您的一切消失得無影無蹤,我、 Sun/Oracle和IBM都將不負責任。爲以防萬一,建議先在虛擬(很是生產)環境中實驗。

  在這個時刻您想要的是,在JVM消亡之際捕獲堆的一個快照——正好-XX:+HeapDumpOnOutOfMemoryError命令能夠完成這一操做。

  運行該命令通知JVM拍攝一個「堆轉儲快照」,並將其保存在一個文件中以便處理,一般使用jhat實用工具(我在上一篇文章中介紹過)。您可使用相應的-XX:HeapDumpPath標誌指定到保存文件的實際路徑。(無論文件保存在哪,務必確保文件系統和/或Java流程必需要有權限配置,能夠在其中寫入。)

  3.bootclasspath

 按期將一個類放入類路徑是頗有幫助的,這類路徑與庫存JRE附帶的類路徑或者以某種方式擴展的JRE類路徑略有不一樣。(新Java Crypto API提供商就是一個例子)。若是您想要擴展JRE,那麼您定製的實現必須可使用引導程序ClassLoader,該引導程序能夠加載rt.jar中的 java.lang.Object及其全部相關文件。

  儘管您能夠非法打開rt.jar並將您的定製實現或新數據包移入其中,但從技術上您就違反了您下載JDK時贊成的協議了。

  相反,使用JVM本身的-Xbootclasspath選項,以及皮膚-Xbootclasspath/p和-Xbootclasspath/a。

  -Xbootclasspath使您能夠設置完整的引導類路徑(這一般包括一個對rt.jar的引用),以及一些其餘JDK附帶的(不是 rt.jar的一部分)JAR文件。-Xbootclasspath/p將值前置到現有bootclasspath中,並將 -Xbootclasspath/a附加到其中。

  例如,若是您修改了庫中的java.lang.Integer,並將修改放在一個子路徑mods下,那麼-Xbootclasspath/amods參數將新Integer放在默認的參數前面。

  4.verbose

  對於虛擬的或任何類型的Java應用程序,-verbose是一個頗有用的一級診斷使用程序。該標誌有三個子標誌:gc、class和jni。

  開發人員嘗試尋找是否 JVM 垃圾收集器發生故障或者致使性能低下,一般首先要作的就是執行 gc。不幸的是,解釋 gc 輸出很麻煩 — 足夠寫一本書。更糟糕的是,在命令行中打印的輸出在不一樣的 Java 版本中或者不在不一樣的 JVM 中會發生改變,這使得正確解釋變得更難。

  通常來講,若是垃圾收集器是一個分代收集器(多數「企業級」VMs都是)。某種虛擬標誌將會出現,來指出一個所有清掃GC通路;在Sun JVM中,標誌在GC輸出行的開始以「[FullGC...]」形式出現。

  想要診斷ClassLoader和/或不匹配的類衝突,class能夠幫上大忙。它不只報告類什麼時候加載,還報告類從何處加載,包括到JAR的路徑(若是來自JAR)。

  jni不多使用,除了使用JNI或本地庫時。打開時,它將報告各類JNI事件,好比,本地庫什麼時候加載,方法什麼時候彈回;再一次強調,在不一樣JVM版本中,輸出會發生變化。

  5.Command-line-X

  我列出了JVM中提供的我喜歡的命令行選項,可是還有一些更多的須要您本身發現,運行命令行參數-X,列出JVM提供的全部非標準(但大部分都是安全的)參數—例如:

  -Xint,在解釋模式下運行JVM(對於測試JIT編譯器其實是否對您的代碼起做用或者驗證是否JIT編譯器中有一個bug,這都頗有用)。

  -Xloggc:,和-verbose:gc作一樣的事,可是記錄一個文件而不輸出到命令行窗口。

  JVM命令行選項時常發生變化,所以,按期查看是一個好主意。甚至,您深夜盯着監控器和下午5點回家和妻子孩子吃頓晚飯,(或者在Mass Effect 2中消滅您的敵人,根據您的喜愛),它們都是不同的。

  結束語

  在生產環境中,命令行標誌不是爲永久使用而設計的——事實上,除了您終止用來調優JVM垃圾收集器的標誌,沒有一個非標準命令行標記是專用於生產使用的。可是,做爲工具來刺探在其餘方面徹底不透明的虛擬機的內部工做,是很是有用的。

http://www.51testing.com/html/28/116228-223890.html

相關文章
相關標籤/搜索