首页 » linux » 正文

内存jvm参数调整总结

对tomcat 7.0 下堆内存告警的情况进行了总结,线上jdk1.6使用的GC策略为:-XX:+UseParallelGC ,即新生代为并行GC年老代为串行GC,jdk1.7默认GC方式为-XX:+UseParallelOldGC ,即新生代和年老代均为并行GC。修改方式为,修改jdk1.7的GC策略为-XX:+UseConcMarkSweepGC (并发GC策略,仅标记阶段会暂停工作线程,响应优先,会较多较快的执行FullGc)。

监控报表的应用等也都遇到了堆内存超过80%的问题,其中一些应用是jdk1.6,也有jdk1.7。参照调整

 

原选项(或默认选项)

-XX:+UseParallelGC

 

修改为:

-XX:+UseConcMarkSweepGC

 

后,观察发现,young gc的次数明显增多,Full gc没有明显增长,堆内存随着时间推移仍然缓慢增长,待增长到一定时间,仍然有堆内存超过80%的告警。告警之后,Full gc之后,告警消失。于是分析,应该是年轻代内存上限不够,另外,能否通过适当增加Full gc的次数,对年老代进行及时回收。通过参考相关文档,旧生代并发回收的触发时机为:

1、当旧生代空间使用到一定比率时触发;

JDK V 1.6中默认为92%,可通过PrintCMSInitiationStatistics(此参数在V 1.5中不能用)来查看这个值到底是多少;

可通过CMSInitiatingOccupancyFraction来强制指定,默认值并不是赋值在了这个值上,是根据如下公式计算出来的:

((100 – MinHeapFreeRatio) +(double)(CMSTriggerRatio * MinHeapFreeRatio) / 100.0)/ 100.0;

MinHeapFreeRatio默认值: 40   CMSTriggerRatio默认值: 80

 

2、当perm gen采用CMS收集且空间使用到一定比率时触发;

perm gen采用CMS收集需设置:-XX:+CMSClassUnloadingEnabled

JDK V 1.6中默认为92%;

可通过CMSInitiatingPermOccupancyFraction来强制指定,同样,它是根据如下公式计算出来的:

((100 – MinHeapFreeRatio) +(double)(CMSTriggerPermRatio* MinHeapFreeRatio) / 100.0)/ 100.0;

MinHeapFreeRatio默认值: 40    CMSTriggerPermRatio默认值: 80

 

3、Hotspot根据成本计算决定是否需要执行CMS GC;

可通过-XX:+UseCMSInitiatingOccupancyOnly来去掉这个动态执行的策略。

4、外部调用了System.gc,且设置了ExplicitGCInvokesConcurrent;

需要注意,在JDK 6中,在这种情况下如应用同时使用了NIO,可能会出现bug

 

另外有两个重要的表格参考:

新生代GC方式 旧生代和持久代GC方式
-XX:+UseSerialGC 串行GC 串行GC
-XX:+UseParallelGC PS GC 并行MSC GC
-XX:+UseConcMarkSweepGC ParNew GC 并发GC

当出现concurrent Mode

failure时采用串行GC

-XX:+UseParNewGC 并行GC 串行GC
-XX:+UseParallelOldGC PS GC 并行Compacting GC
-XX:+UseConcMarkSweepGC

-XX:-UseParNewGC

串行GC 并发GC

当出现Concurrent Mode

failure或promotion failed

时则采用串行GC

不支持的组合方式 1、-XX:+UseParNewGC –XX:+UseParallelOldGC

2、-XX:+UseParNewGC –XX:+UseSerialGC

 

 

GC方式 常用参数(-Xms –Xmx –Xmn –XX:PermSize –XX:MaxPermSize
新生代可用GC 串行GC -XX:SurvivorRatio,默认为8,代表eden:survivor;

-XX:MaxTenuringThreshold,默认为15,代表对象在新生代经历多少次minor gc后

才晋升到旧生代;

PS GC -XX:InitialSurvivorRatio,默认为8,代表new gen:survivor;

-XX:SurvivorRatio,默认值对于PS GC无效,但仍然可设置,代表eden:survivor;

-XX:-UseAdaptiveSizePolicy,不允许PS GC动态调整eden、s0、s1的大小,

此时-XX:MaxTenuringThreshold也可使用;

-XX:ParallelGCThreads,设置并行GC的线程数。

ParNew GC 同串行。
旧生代和持久代可用GC 串行GC 无特殊参数。
并行GC

(包括MSC、

Compacting)

-XX:ParallelGCThreads,设置并行GC的线程数。

-XX:+ScavengeBeforeFullGC,Full GC前触发Minor GC

并发GC -XX:ParallelCMSThreads,设置并发CMS GC时的线程数;

-XX:CMSInitiatingOccupancyFraction,当旧生代使用比率占到多少百分比时触发CMS GC;

-XX:+UseCMSInitiatingOccupancyOnly,默认为false,代表允许hotspot根据成本来决定

什么时候执行CMS GC;

-XX:+UseCMSCompactAtFullCollection,当Full GC时执行压缩;

-XX:CMSMaxAbortablePrecleanTime=5000,设置preclean步骤的超时时间,单位为毫秒;

-XX:+CMSClassUnloadingEnabled,Perm Gen采用CMS GC回收。

 

经过以上分析,调整内存参数为:

 

-Xms4096m -Xmx4096m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -Xmn2048M -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled

 

具体含义如下:

XmsXmx就不用说了,

-XX:MaxPermSize最大持久代内存512M

-XX:+UseConcMarkSweepGC 使用年轻代和年老代都并行gc的方式,并且gc的时间短,old gc的次数取决于stop the world(中断响应)的次数,尽量减少对应用响应的影响。

-Xmn2048M:设置新生代内存的上限大小为2g,这是为了减少young gc的次数,因为默认内存分配是会从新生代内存中分配的。

-XX:+UseCMSInitiatingOccupancyOnly: 不加这个选项的话,根据成本计算决定是否需要执行CMS gc,加上这个选项,当旧生代空间使用率达到92%时会无条件执行Full GC

-XX:+CMSClassUnloadingEnabled :CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,需要设置此选项。

 

其实还有两个选项可以考虑:

CMSInitiatingOccupancyFraction: 当旧生代空间使用到一定比率时, 强制执行旧生代的Full GC。默认为92%。这个参数如果设置为50左右的话,Full GC的次数会非常频繁。可能会对应用的性能造成一定影响。

CMSInitiatingPermOccupancyFraction: 当持久代里的使用比例达到一定比率时,进行持久代内存的回收,默认为92%。如果调低的话,也会明显增多持久代gc的次数。

但这个选项也可能对应用的性能造成影响,所以使用需要谨慎。

 

 

 

调整前的堆内存一天内变化趋势,可以看到虽然在调整,但是整体堆内存使用仍然呈增长态势,可以分析是Full GC的次数不够。

发表评论