詳解JVM參數配置技巧
這里向大家描述一下JVM參數配置的具體步驟,比如heapsize的配置,-Xms<n>指定jvm的最小heap大小,如:-Xms=2g,高并發應用,建議和-Xmx一樣,防止因為內存收縮/突然增大帶來的性能影響。
JVM參數配置詳解
1:JVM參數配置之heapsize
a:-Xmx<n>
指定jvm的最大heap大小,如:-Xmx=2g
b:-Xms<n>
指定jvm的最小heap大小,如:-Xms=2g,高并發應用,建議和-Xmx一樣,防止因為內存收縮/突然增大帶來的性能影響。
c:-Xmn<n>
指定jvm中NewGeneration的大小,如:-Xmn256m。這個參數很影響性能,如果你的程序需要比較多的臨時內存,建議設置到512M,如果用的少,盡量降低這個數值,一般來說128/256足以使用了。
d:-XX:PermSize=<n>
指定jvm中PermGeneration的最小值,如:-XX:PermSize=32m。這個參數需要看你的實際情況,。可以通過jmap命令看看到底需要多少。
e:-XX:MaxPermSize=<n>
指定PermGeneration的最大值,如:-XX:MaxPermSize=64m
f:-Xss<n>
指定線程桟大小,如:-Xss128k,一般來說,webx框架下的應用需要256K。如果你的程序有大規模的遞歸行為,請考慮設置到512K/1M。這個需要全面的測試才能知道。不過,256K已經很大了。這個參數對性能的影響比較大的。
g:-XX:NewRatio=<n>
指定jvm中OldGenerationheapsize與NewGeneration的比例,在使用CMSGC的情況下此參數失效,如:-XX:NewRatio=2
h:-XX:SurvivorRatio=<n>
指定NewGeneration中EdenSpace與一個SurvivorSpace的heapsize比例,-XX:SurvivorRatio=8,那么在總共NewGeneration為10m的情況下,EdenSpace為8m
i:-XX:MinHeapFreeRatio=<n>
指定jvmheap在使用率小于n的情況下,heap進行收縮,Xmx==Xms的情況下無效,如:-XX:MinHeapFreeRatio=30
j:-XX:MaxHeapFreeRatio=<n>
指定jvmheap在使用率大于n的情況下,heap進行擴張,Xmx==Xms的情況下無效,如:-XX:MaxHeapFreeRatio=70
k:-XX:LargePageSizeInBytes=<n>
指定Javaheap的分頁頁面大小,如:-XX:LargePageSizeInBytes=128m#p#
2:JVM參數配置之garbagecollector
a:-XX:+UseParallelGC
指定在NewGeneration使用parallelcollector,并行收集,暫停appthreads,同時啟動多個垃圾回收thread,不能和CMSgc一起使用.系統噸吐量優先,但是會有較長長時間的apppause,后臺系統任務可以使用此gc
b:-XX:ParallelGCThreads=<n>
指定parallelcollection時啟動的thread個數,默認是物理processor的個數,
c:-XX:+UseParallelOldGC
指定在OldGeneration使用parallelcollector
d:-XX:+UseParNewGC
指定在NewGeneration使用parallelcollector,是UseParallelGC的gc的升級版本,有更好的性能或者優點,可以和CMSgc一起使用
e:-XX:+CMSParallelRemarkEnabled
在使用UseParNewGC的情況下,盡量減少mark的時間
f:-XX:+UseConcMarkSweepGC
指定在OldGeneration使用concurrentcmarksweepgc,gcthread和appthread并行(在init-mark和remark時pauseappthread).apppause時間較短,適合交互性強的系統,如webserver
g:-XX:+UseCMSCompactAtFullCollection
在使用concurrentgc的情況下,防止memoryfragmention,對liveobject進行整理,使memory碎片減少
h:-XX:CMSInitiatingOccupancyFraction=<n>
指示在oldgeneration在使用了n%的比例后,啟動concurrentcollector,默認值是68,如:-XX:CMSInitiatingOccupancyFraction=70
有個bug,在低版本(1.5.09andearly)的jvm上出現,http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6486089
i:-XX:+UseCMSInitiatingOccupancyOnly
指示只有在oldgeneration在使用了初始化的比例后concurrentcollector啟動收集#p#
3:JVM參數配置之其他
a:-XX:MaxTenuringThreshold=<n>
指定一個object在經歷了n次younggc后轉移到oldgeneration區,在linux64的java6下默認值是15,此參數對于throughputcollector無效,如:-XX:MaxTenuringThreshold=31
b:-XX:+DisableExplicitGC
禁止java程序中的fullgc,如System.gc()的調用.最好加上么,防止程序在代碼里誤用了。對性能造成沖擊。
c:-XX:+UseFastAccessorMethods
get,set方法轉成本地代碼
d:-XX:+PrintGCDetails
打應垃圾收集的情況如:
[GC15610.466:[ParNew:229689K->20221K(235968K),0.0194460secs]1159829K->953935K(2070976K),0.0196420secs]
e:-XX:+PrintGCTimeStamps
打應垃圾收集的時間情況,如:
[Times:user=0.09sys=0.00,real=0.02secs]
f:-XX:+PrintGCApplicationStoppedTime
打應垃圾收集時,系統的停頓時間,如:
Totaltimeforwhichapplicationthreadswerestopped:0.0225920seconds
4:awebserverproductsampleandprocess
- JAVA_OPTS="-server-Xmx2g-Xms2g-Xmn256m
- -XX:PermSize=128m-Xss256k-XX:+DisableExplicitGC
- -XX:+UseConcMarkSweepGC-XX:+UseParNewGC
- -XX:+CMSParallelRemarkEnabled-XX:+UseCMSCompactAtFullCollection
- -XX:LargePageSizeInBytes=128m-XX:+UseFastAccessorMethods
- -XX:+UseCMSInitiatingOccupancyOnly
- -XX:CMSInitiatingOccupancyFraction=70"
最初的時候我們用UseParallelGC和UseParallelOldGC,heap開了3G,NewRatio設成1.這樣的配置下younggc發生頻率約12,3秒一次,平均每次花費80ms左右,fullgc發生的頻率極低,每次消耗1s左右.從所有gc消耗系統時間看,系統使用率還是滿高的,但是不論是younggc還是oldgc,applicatonthreadpause的時間比較長,不合適web應用.我們也調小NewGeneration的,但是這樣會使fullgc時間加長.
后來我們就用CMSgc(-XX:+UseConcMarkSweepGC),當時的總heap還是3g,新生代1.5g后,觀察不是很理想,改為jvmheap為2g新生代設置-Xmn1g,在這樣的情況下younggc發生的頻率變成,7,8妙一次,平均每次時間40~50毫秒左右,CMSgc很少發生,每次時間在init-mark和remark(twostepsstopallappthread)總共平均花費80~90ms左右.
在這里我們曾經NewGeneration調大到1400m,總共2g的jvmheap,平均每次ygc花費時間60~70ms左右,CMSgc的init-mark和remark之和平均在50ms左右,這里我們意識到錯誤的方向,或者說CMS的作用,所以進行了修改
最后我們調小NewGeneration為256m,younggc2,3秒發生一次,平均停頓時間在25毫秒左右,CMSgc的init-mark和remark之和平均在50ms左右,這樣使系統比較平滑,經壓力測試,這個配置下系統性能是比較高的
在使用CMSgc的時候他有兩種觸發gc的方式:gc估算觸發和heap占用觸發.我們的1.5.0.09環境下有次old區heap占用再30%左右,她就頻繁gc,個人感覺系統估算觸發這種方式不靠譜,還是用heap使用比率觸發比較穩妥.
這些數據都來自64位測試機,過程中的數據都是我在jbosslog找的,當時沒有記下來,可能存在一點點偏差,但不會很大,基本過程就是這樣.
5:JVM參數配置總結
webserver作為交互性要求較高的應用,我們應該使用Parallel+CMS,UseParNewGC這個在jdk6-server上是默認的,newgenerationgc,新生代不能太大,這樣每次pause會短一些.CMSmark-sweepgeneration可以大一些,可以根據pausetime實際情況控制
【編輯推薦】