Java啓動參數的思考

前幾年在將OS從32 bit升級到64 bit,以及虛擬機的內存調整到8G後,我把應用的Java啓動參數從新寫了一版,做爲目前大部分Java應用的默認啓動參數模版,這幾年下來,發如今這個標準版的啓動參數上仍是犯了一些錯誤的。web

1. -XX:+DisableExplicitGC
Java在實現RMI Server的時候會經過定時的調System.gc來強制作GC(即便程序裏沒用到RMI也會被啓動),這個動做很是煩人,另外也是爲了不應用代碼上顯式去調用System.gc致使一些不必的GC動做產生,因此當時就直接加上了這個參數。ubuntu

如今來看,這個參數有個挺大的問題是,Direct ByteBuffer所佔用的內存以及FileChannel.map所佔用的內存當達到了他們的最大閾值時,須要依賴調用System.gc來強制釋放下,若是加上了這個啓動參數,就意味着這個強制的釋放就無效了,這會致使的一個問題是,當old gen還沒到達觸發full gc/cms gc的條件,而堆外的Direct ByteBuffer/FileChannel.map佔用的空間又超過了它們的最大閾值時,就會直接致使OOM,而這種狀況下頗有可能實際上是能夠藉助顯式調用System.gc來釋放出足夠的空間,不過話說我仍然以爲這是JDK設計上應該改進的一點,不該該在這個時候須要依賴System.gc來管理堆外的空間,你們能夠翻下FileChannel.map的代碼就會發現那裏在等待System.gc執行的結果是寫S的等待100ms,事實上不多有full gc/cms gc能夠在100ms完成。測試

不過鑑於上面的情況,若是應用裏有使用到很多Direct ByteBuffer或FileChannel.map的話,建議仍是不要開啓-XX:+DisableExplicitGC,若是是cms gc的,仍是改成加上這個參數-XX:+ExplicitGCInvokesConcurrent,另外若是有RMI Server這種定時GC影響的,再調整下-Dsun.rmi.dgc.client.gcInterval和-Dsun.rmi.dgc.server.gcInterval這兩個時間吧,時間單位是ms,也能夠設置爲Long.MAX_VALUE。spa

2. 缺乏-XX:+UseCMSInitiatingOccupancyOnly
因爲咱們的Java應用的heap基本都是大於4G的,因此都是用的CMS,當時我在寫啓動參數的時候一直猶豫要不要加上-XX:+UseCMSInitiatingOccupancyOnly這個參數,一猶豫就沒加,但事實上後來碰到了很多應用因爲JVM自行觸發CMS GC的機制致使CMS GC頻繁,因此建議用CMS GC的場景下仍是加上這個參數更穩妥。設計

3. -XX:MaxDirectMemorySize
話說在寫啓動參數的時候我都壓根不知道這參數(要知道Java到底有哪些啓動參數可用,以及默認值是多少,最靠譜的方法是在啓動參數上加-XX:+PrintFlagsFinal或用jinfo -flags [pid]來查看),後來是因爲有一次出現了有應用物理內存被耗光,排查的時候才發現是Direct ByteBuffer這塊默認的大小是heap size,因此在有些狀況下可能會出現Direct ByteBuffer這裏佔用了大量的空間,但heap這邊又還不到觸發Full gc/CMS gc的條件,就會有可能致使物理內存被耗光。
所以對於遠程交互比較多的應用,建議仍是加上這個參數,合理控制大小,不要讓heap size+Direct Memory Size就把物理內存給耗光了。調試

ps: 關於Java常見問題的排查方法,從新專門寫了一個PPT,涵蓋了如下幾種常見的Java問題的排查方法:
1. 類加載問題,例如NoSuchMethodException;
2. 內存問題,例如各類OOM;
3. 應用無響應問題,例如http訪問後返回499;
4. CPU利用率問題,例如us耗盡;
5. Java進程退出問題。日誌

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------code

JVM8.0以後web推薦的配置:server

JAVA_OPTS='-server -Xms256m -Xmx512m -XX:NewSize=128m -XX:MaxNewSize=256m -XX:MaxMetaspaceSize=256m 

-XX:+UseConcMarkSweepGC -XX:+UseCompressedOops -XX:MaxGCPauseMillis=50  -XX:+CMSParallelRemarkEnabled -XX:+CMSClassUnloadingEnabled

-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/home/ubuntu/gc.log'

其中blog

-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/home/ubuntu/gc.log

參數用於開發和測試調試,查看JVM的相關gc日誌

相關文章
相關標籤/搜索