JVM GC调优

1、基本概念

heap=young+old,不包括perm区

young=eden + from_survivor + to_survivor,实际可用的大小是eden + to_survivor

串行收集器-单cpu使用,相对高效

并行收集器-多cpu,吞吐量优先时使用

并发收集器-多cpu,停顿时间优先时使用(web应用一般用这个)

2、基本JVM参数

-Xmx64m 最大heap大小,默认物理内存的1/4(但是限制<1GB)

-Xms64m 初始heap大小,默认物理内存的1/64(但是限制<1GB)

-Xmn12m young代大小,sun推荐整个heap的3/8,太大会减少old的大小,引发较频繁的major gc

-Xss256k 每个线程的堆栈大小,一般256就ok了

-XX:SurvivorRatio=16 eden与一个survivor的比值,默认是8

-XX:+DisableExplicitGC 关闭System.gc()

3、CMS收集相关参数

-XX:+UseConcMarkSweepGC 使用CMS内存收集

-XX:+UseCMSCompactAtFullCollection 在full gc的时候,对old区压缩

-XX:CMSFullGCsBeforeCompaction=1 多少次full gc后进行old区压缩,cms会产生old区"碎片",要进行整理,避免没有连续空间放大对象而引发cms failure出现

-XX:CMSInitiatingOccupancyFraction=70 old区使用70%后开始CMS收集,jdk5默认68%,jdk6默认92%

-XX:CMSInitiatingPermOccupancyFraction=70 perm区使用70%后开始CMS收集,jdk5默认68%,jdk6默认92%

-XX:+CMSClassUnloadingEnabled 允许perm区不够引发full gc时perm区的类卸载

-XX:+UseParNewGC 设置年轻代为并行收集

-XX:ParallelGCThreads=4 并行收集器的线程数,此值最好配置与处理器数目相等

-XX:MaxTenuringThreshold=3 垃圾最大年龄,jdk5之前,cms收集器默认为0,jdk6默认为4

4、GC日志辅助参数

-XX:+PrintGCDetails 输出gc详细信息

-XX:+PrintGCTimeStamps 输出gc时间戳,java 6之后使用-XX:+PrintGCDateStamps,阅读更方便

-Xloggc:filename gc日志文件路径

-XX:+PrintTenuringDistribution survivor的对象进入old区之前进行了几次copy,与设置的-XX:MaxTenuringThreshold比较,调整此值和survivor大小

5、各个参数调整经验

heap大小:在保证os顺畅运转的前提下,heap尽量大。

young区:

尽量大,过小可能引发频繁major gc,降低吞吐量,同时可能导致对象直接进入old区,如果old满了,触发full gc;

过大会引起回收耗时过长,导致应用停顿,gui程序不要太大的young区。

old区:

过大会导致old回收过慢,应用停顿较长(实际上cms回收是很快的,所以尽量大些,减少cms gc频率);

过小会导致产生old区小碎片,放不下大对象,引起频繁full gc。

如果用了缓存,old区要适当大些,同时缓存不应该无限增长。

young与old的调整原则:要考虑old区的耗时、频率,尽可能降低这两个值。

6、minor gc,回收young区

当young代满了(即eden区放不下新创建的对象),触发minor gc,只回收young区的对象,old区不回收。

young区被回收的对象越多,gc速度越快,因为young区采用的是“复制”的方式,即把enden区和survivor的from区存活对象复制到survivor的to区。

如果设置了-XX:MaxTenuringThreshold=N参数,survivor的from区对象到to的复制达到了N次,进入old区,如果to区装不下,直接进入old区。

关于promotion failed:

引发的两个原因:

1)survivor太小了,survivor里面的对象还没有到达进入old的copy次数

2)进入old区的对象太多,而old区已经不够用了

这两个情况都会引发full gc,导致停顿较长。

第一个可以调整survivor的大小,或者直接去掉-XX:MaxTenuringThreshold参数,minor gc回收不掉直接进入old区;

第二个可以调小young、增大old的大小(尽早触发minor gc,减少每次进入old的对象数量),或者调小-XX:CMSInitiatingOccupancyFraction(尽早触发old的回收)

7、cms gc,回收old区

步骤:initial-mark> concurrent-mark> concurrent-preclean> remark> concurrent-sweep> concurrent-reset

除了initial-mark、remark之外,不暂停应用。

关于concurrent mode failure:

引发的两个原因

1)年老代变满之前,old区垃圾回收还没有完成

2)新空间分配请求在年老代的剩余空间中无法得到满足,日志:[GC 90010.628: [ParNew: 261760K->261760K(261952K), 0.0000350secs]90010.628: [CMS (concurrent mode failure)

第一个需要调小old区,或者调小参数-XX:CMSInitiatingOccupancyFraction=70,以尽快回收old区,减少old回收时间;

第二个需要减少young、增加old的大小,或者使用-XX:CMSFullGCsBeforeCompaction并设置较小的值,提高full gc后压缩old的频次,避免young大对象无法晋升到old。


转自:http://www.bdqn.cn/news/201305/8932.shtml


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值