2010年9月21日

[Lighter Java] Select Java Client / Server VM

最近發現一些啟動java vm的參數,會影響到伺服器運作的效能。若執行的程式很小,不太需要調校,但是對Tomcat、JBoss等J2EE container來說,一些參數的設定就會有比較明顯的影響。

JVM在啟動時,會依據作業系統及處理器核心數量、記憶體容量判別 Client 或 Server 兩種機器類型。

從Oracle提供的「Server-Class Machine Detection」文件來看,Java SE6對伺服器等級機器(server-class machine)的定義為:「至少擁有2個核心以上的處理器、2個Gigabyte以上的實體記憶體。」

實際啟動JVM時,也會根據作業系統的不同而有預設的差異。
  1. 在AMD64平台上,不管Solaris/Windows/Linux預設都是server vm,並且不提供client vm。
  2. 在x86(i586)平台,除Windows是預設client vm,其他Solaris/Linux則是依照伺服器等級,若條件符合就預設server vm,否則還是會使用client vm。
所以需要調整的情況,就是當作業系統為32位元的Windows,擁有足夠的記憶體容量及多核心處理器,而java卻選擇client vm,我們需要手動指定server vm。另一種情況則是32位元的Linux伺服器,雖然未達到Java SE6定義的伺服器等級,但那部伺服器專跑J2EE應用,可以佔用大部分系統資源,仍可指定為server vm。

並非每一種情況用server vm執行都會比較好,依照Oracle提供的文件所述,server vm在啟動時可能會比較慢,但長時間運作來看則會較好的效能。

要判別java預設用哪一種vm,可以用 java -version 查詢。

例如這是一個server vm的輸出。
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

以下則是client vm的輸出。
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

在java後面添加 -server 或 -client 參數,可以建議java使用指定的 client或server vm。
  1. java -server
  2. java -client
要測試java是否依照參數啟動,同樣用-version指令。
  1. java -server -version
  2. java -client -version
有些情況下, java -server 會跑出以下的錯誤訊息。
Error: no `server' JVM at `C:\Program Files\Java\jre6\bin\server\jvm.dll'.

這種情況是因為安裝的Java Runtime並未包含server vm需要的支援,我們需要將環境變數的PATH設定,重新指定為JDK的bin路徑,例如「c:\Program Files\Java\jdk1.6.0_21」。

"c:\Program Files\Java\jdk1.6.0_21\bin\java.exe" -server -version

要設置 -server 最好不要直接寫在 JAVA_OPTS ,因為對於一些GUI應用程式或Applet來說,用server vm執行並不見得比較好;因此設定在 CATALINA_OPTS (tomcat) 或 JBOSS_OPTS (jboss) 是比較好的選擇。

圖片來源:The Java HotSpot Performance Engine Architecture
根據Java HotSpot白皮書的說明,Client VM的編譯器不像Server  VM執行很多的最佳化,所以花比較少時間分析和編譯代碼,因此Client VM啟動速度較快。


The Client VM compiler does not try to execute many of the more complex optimizations performed by the compiler in the Server VM, but in exchange, it requires less time to analyze and compile a piece of code. This means the Client VM can start up faster and requires a smaller memory footprint.

延伸閱讀:

2 則留言:

  1. Excellent tutorial! It is really helpful for me, as a java beginner. I want to use java to write a java barcode generator, which I saw from “http://www.onbarcode.com/tutorial/java-barcode-generation.html ”. It is easy-use, I want to write one like it.

    回覆刪除
  2. Take a look at Groovy + Java2D.

    http://groovy.dzone.com/articles/java2d-groovy-way
    http://groovy.codehaus.org/GraphicsBuilder

    回覆刪除

lyhcode by lyhcode
歡迎轉載,請務必註明出處!