JVM参数调优是一个很头痛的问题可能和应用有关系别人说可以的对自己不一定管用下面是本人一些JVM调优的实践经验希望对读者能有帮助环境LinuxASresinJDKCPUG内存dell服务器 JVM调优 一JVM调优之串行垃圾回收 也就是默认配置完成万request用时秒JVM参数配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserver XmsMXmxMXmnM XX:PermSize=MXX:MaxPermSize=M XX:MaxTenuringThreshold=XX:GCTimeRatio= XnoclassgcXloggc:log/gclog XX:+PrintGCDetailsXX:+PrintGCTimeStamps; 这种配置一般在resin启动小时内似乎没有大问题网站可以正常访问但查看日志发现在接近小时时FullGC执行越来越频繁大约每隔分钟就有一次FullGC每次FullGC系统会停顿秒左右作为一个网站来说用户等待秒恐怕太长了所以这种方式有待改善MaxTenuringThreshold=表示一个对象如果在救助空间移动次还没有被回收就放入年老代GCTimeRatio=表示java可以用%的时间来做垃圾回收/(+)=/=% 二JVM调优之并行回收 完成万request用时秒配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserverXmxM XmsMXmnMXX:PermSize=MXX:MaxPermSize=M XnoclassgcXloggc:log/gclogXX:+PrintGCDetails XX:+PrintGCTimeStampsXX:+UseParallelGCXX:ParallelGCThreads= XX:+UseParallelOldGCXX:MaxGCPauseMillis= XX:+UseAdaptiveSizePolicyXX:MaxTenuringThreshold= XX:GCTimeRatio=; 并行回收我尝试过多种组合配置似乎都没什么用resin启动小时左右就会停顿时间超过秒也有可能是参数设置不够好的原因MaxGCPauseMillis表示GC最大停顿时间在resin刚启动还没有执行FullGC时系统是正常的但一旦执行FullGCMaxGCPauseMillis根本没有用停顿时间可能超过秒之后会发生什么我也不再关心了赶紧重启resin尝试其他回收策略 三JVM调优之并发回收 完成万request用时秒比并行回收差不多快一倍是默认回收策略性能的倍配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserver XmsMXmxMXmnMXX:PermSize=M XX:MaxPermSize=MXX:+UseConcMarkSweepGC XX:MaxTenuringThreshold=XX:GCTimeRatio= XnoclassgcXloggc:log/gclogXX:+PrintGCDetails XX:+PrintGCTimeStampsXX:+UseCMSCompactAtFullCollection XX:CMSFullGCsBeforeCompaction=; 这个配置虽然不会出现秒连不上的情况但系统重启个小时左右每隔几分钟就会有秒连不上的情况查看gclog发现在执行ParNewGC时有个promotionfailed错误从而转向执行FullGC造成系统停顿而且会很频繁每隔几分钟就有一次所以还得改善UseCMSCompactAtFullCollection是表是执行FullGC后对内存进行整理压缩免得产生内存碎片CMSFullGCsBeforeCompaction=N表示执行N次FullGC后执行内存压缩 四JVM调优之增量回收 完成万request用时秒太慢了配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserver XmsMXmxMXmnMXX:PermSize=M XX:MaxPermSize=MXX:MaxTenuringThreshold= XX:GCTimeRatio=XnoclassgcXloggc:log/gclog XX:+PrintGCDetailsXX:+PrintGCTimeStampsXincgc; 似乎回收得也不太干净而且也对性能有较大影响不值得试 五JVM调优之并发回收的ICMS模式 和增量回收差不多完成万request用时秒配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserver XmsMXmxMXmnMXX:PermSize=M XX:MaxPermSize=MXX:MaxTenuringThreshold= XX:GCTimeRatio=XnoclassgcXloggc:log/gclog XX:+PrintGCDetailsXX:+PrintGCTimeStamps XX:+UseConcMarkSweepGCXX:+CMSIncrementalMode XX:+CMSIncrementalPacing XX:CMSIncrementalDutyCycleMin= XX:CMSIncrementalDutyCycle=XX:TraceClassUnloading; 采用了sun推荐的参数回收效果不好照样有停顿数小时之内就会频繁出现停顿什么sun推荐的参数照样不好使 六JVM调优之递增式低暂停收集器 又叫什么火车式回收完成万request用时秒配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserver XmsMXmxMXmnMXX:PermSize=M XX:MaxPermSize=MXX:MaxTenuringThreshold= XX:GCTimeRatio=XnoclassgcXloggc:log/gclog XX:+PrintGCDetailsXX:+PrintGCTimeStampsXX:+UseTrainGC; 该配置效果也不好影响性能所以没试 七相比之下还是并发回收比较好性能比较高只要能解决ParNewGC(并行回收年轻代)时的promotionfailed错误就一切好办了查了很多文章发现引起promotionfailed错误的原因是CMS来不及回收(CMS默认在年老代占到%左右才会执行)年老代又没有足够的空间供GC把一些活的对象从年轻代移到年老代所以执行FullGCCMSInitiatingOccupancyFraction=表示年老代占到约%时就开始执行CMS这样就不会出现FullGC了SoftRefLRUPolicyMSPerMB这个参数也是我认为比较有用的官方解释是softlyreachableobjectswillremainaliveforsomeamountoftimeafterthelasttimetheywerereferencedThedefaultvalueisonesecondoflifetimeperfreemegabyteintheheap我觉得没必要等秒所以设置成配置如下 $JAVA_ARGS=Dresinhome=$SERVER_ROOTserverXmsM XmxMXmnMXX:PermSize=MXX:MaxPermSize=M XX:SurvivorRatio=XX:MaxTenuringThreshold= XX:GCTimeRatio=XnoclassgcXX:+DisableExplicitGC XX:+UseParNewGCXX:+UseConcMarkSweepGC XX:+CMSPermGenSweepingEnabled XX:+UseCMSCompactAtFullCollection XX:CMSFullGCsBeforeCompaction= XX:+CMSClassUnloadingEnabledXX:CMSParallelRemarkEnabled XX:CMSInitiatingOccupancyFraction= XX:SoftRefLRUPolicyMSPerMB=XX:+PrintClassHistogram XX:+PrintGCDetailsXX:+PrintGCTimeStamps XX:+PrintGCApplicationConcurrentTime XX:+PrintGCApplicationStoppedTime Xloggc:log/gclog; 上面这个配置内存上升的很慢小时之内几乎没有停顿现象最长的只停滞了sParNewGC每秒左右才执行一次每次回收约秒看来问题应该暂时解决了 |