详解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>
指定线程C大小,如:-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

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启动收集

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参数配置总结

相关推荐