这里向大家描述一下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实际情况控制
【编辑推荐】