JVM參數調優是一個很頭痛的問題
可能和應用有關系
別人說可以的對自己不一定管用
下面是本人一些JVM調優的實踐經驗
希望對讀者能有幫助
環境LinuxAS
resin
JDK
CPU
G內存
dell
服務器
JVM調優
一
JVM調優之串行垃圾回收
也就是默認配置
完成
萬request用時
秒
JVM參數配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
;
這種配置一般在resin啟動
小時內似乎沒有大問題
網站可以正常訪問
但查看日志發現
在接近
小時時
FullGC執行越來越頻繁
大約每隔
分鐘就有一次FullGC
每次FullGC系統會停頓
秒左右
作為一個網站來說
用戶等待
秒恐怕太長了
所以這種方式有待改善
MaxTenuringThreshold=
表示一個對象如果在救助空間移動
次還沒有被回收就放入年老代
GCTimeRatio=
表示java可以用
%的時間來做垃圾回收
/(
+
)=
/
=
%
二
JVM調優之並行回收
完成
萬request用時
秒
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xmx
M
Xms
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
XX:+UseParallelGC
XX:ParallelGCThreads=
XX:+UseParallelOldGC
XX:MaxGCPauseMillis=
XX:+UseAdaptiveSizePolicy
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
;
並行回收我嘗試過多種組合配置
似乎都沒什麼用
resin啟動
小時左右就會停頓
時間超過
秒
也有可能是參數設置不夠好的原因
MaxGCPauseMillis表示GC最大停頓時間
在resin剛啟動還沒有執行FullGC時系統是正常的
但一旦執行FullGC
MaxGCPauseMillis根本沒有用
停頓時間可能超過
秒
之後會發生什麼我也不再關心了
趕緊重啟resin
嘗試其他回收策略
三
JVM調優之並發回收
完成
萬request用時
秒
比並行回收差不多快一倍
是默認回收策略性能的
倍
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:+UseConcMarkSweepGC
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
XX:+UseCMSCompactAtFullCollection
XX:CMSFullGCsBeforeCompaction=
;
這個配置雖然不會出現
秒連不上的情況
但系統重啟
個小時左右
每隔幾分鐘就會有
秒連不上的情況
查看gc
log
發現在執行ParNewGC時有個promotionfailed錯誤
從而轉向執行FullGC
造成系統停頓
而且會很頻繁
每隔幾分鐘就有一次
所以還得改善
UseCMSCompactAtFullCollection是表是執行FullGC後對內存進行整理壓縮
免得產生內存碎片
CMSFullGCsBeforeCompaction=N表示執行N次FullGC後執行內存壓縮
四
JVM調優之增量回收
完成
萬request用時
秒
太慢了
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
Xincgc
;
似乎回收得也不太干淨
而且也對性能有較大影響
不值得試
五
JVM調優之並發回收的I
CMS模式
和增量回收差不多
完成
萬request用時
秒
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
XX:+UseConcMarkSweepGC
XX:+CMSIncrementalMode
XX:+CMSIncrementalPacing
XX:CMSIncrementalDutyCycleMin=
XX:CMSIncrementalDutyCycle=
XX:
TraceClassUnloading
;
采用了sun推薦的參數
回收效果不好
照樣有停頓
數小時之內就會頻繁出現停頓
什麼sun推薦的參數
照樣不好使
六
JVM調優之遞增式低暫停收集器
又叫什麼火車式回收
完成
萬request用時
秒
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
Xloggc:log/gc
log
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
XX:+UseTrainGC
;
該配置效果也不好
影響性能
所以沒試
七
相比之下
還是並發回收比較好
性能比較高
只要能解決ParNewGC(並行回收年輕代)時的promotionfailed錯誤就一切好辦了
查了很多文章
發現引起promotionfailed錯誤的原因是CMS來不及回收(CMS默認在年老代占到
%左右才會執行)
年老代又沒有足夠的空間供GC把一些活的對象從年輕代移到年老代
所以執行FullGC
CMSInitiatingOccupancyFraction=
表示年老代占到約
%時就開始執行CMS
這樣就不會出現FullGC了
SoftRefLRUPolicyMSPerMB這個參數也是我認為比較有用的
官方解釋是softlyreachableobjectswillremainaliveforsomeamountoftimeafterthelasttimetheywerereferenced
Thedefaultvalueisonesecondoflifetimeperfreemegabyteintheheap
我覺得沒必要等
秒
所以設置成
配置如下
$JAVA_ARGS
=
Dresin
home=$SERVER_ROOT
server
Xms
M
Xmx
M
Xmn
M
XX:PermSize=
M
XX:MaxPermSize=
M
XX:SurvivorRatio=
XX:MaxTenuringThreshold=
XX:GCTimeRatio=
Xnoclassgc
XX:+DisableExplicitGC
XX:+UseParNewGC
XX:+UseConcMarkSweepGC
XX:+CMSPermGenSweepingEnabled
XX:+UseCMSCompactAtFullCollection
XX:CMSFullGCsBeforeCompaction=
XX:+CMSClassUnloadingEnabled
XX:
CMSParallelRemarkEnabled
XX:CMSInitiatingOccupancyFraction=
XX:SoftRefLRUPolicyMSPerMB=
XX:+PrintClassHistogram
XX:+PrintGCDetails
XX:+PrintGCTimeStamps
XX:+PrintGCApplicationConcurrentTime
XX:+PrintGCApplicationStoppedTime
Xloggc:log/gc
log
;
上面這個配置內存上升的很慢
小時之內幾乎沒有停頓現象
最長的只停滯了
s
ParNewGC每
秒左右才執行一次
每次回收約
秒
看來問題應該暫時解決了
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25923.html