我正在尝试避免在 生产环境 中运行Tomcat中的Grails应用程序的Full GC(来自下面的gc.log示例) . 有关如何更好地配置GC的任何建议?
14359.317: [Full GC 14359.317: [CMS: 3453285K->3099828K(4194304K), 13.1778420 secs] 4506618K->3099828K(6081792K), [CMS Perm : 261951K->181304K(264372K)] icms_dc=0 , 13.1786310 secs] [Times: user=13.15 sys=0.04, real=13.18 secs]
My VM params are as follow:
-Xms = 6G
-Xmx = 6G
-XX:MaxPermSize参数= 1G
-XX:新尺寸= 2G
-XX:MaxTenuringThreshold = 8
-XX:SurvivorRatio = 7
-XX:UseConcMarkSweepGC
-XX:CMSClassUnloadingEnabled
-XX:CMSPermGenSweepingEnabled
-XX:CMSIncrementalMode
-XX:CMSInitiatingOccupancyFraction = 60
-XX:UseCMSInitiatingOccupancyOnly
-XX:HeapDumpOnOutOfMemoryError
-XX:PrintGCDetails
-XX:PrintGCTimeStamps
-XX:PrintTenuringDistribution
通过-Dsun.reflect.inflationThreshold = 0
14169.764: [GC 14169.764: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 15584312 bytes, 15584312 total
- age 2: 20053704 bytes, 35638016 total
- age 3: 13624872 bytes, 49262888 total
- age 4: 14469608 bytes, 63732496 total
- age 5: 10553288 bytes, 74285784 total
- age 6: 11797648 bytes, 86083432 total
- age 7: 12591328 bytes, 98674760 total
: 1826161K->130133K(1887488K), 0.1726640 secs] 5216326K->3537160K(6081792K) icms_dc=0 , 0.1733010 secs] [Times: user=0.66 sys=0.03, real=0.17 secs]
14218.712: [GC 14218.712: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 25898512 bytes, 25898512 total
- age 2: 10308160 bytes, 36206672 total
- age 3: 16927792 bytes, 53134464 total
- age 4: 13493608 bytes, 66628072 total
- age 5: 14301832 bytes, 80929904 total
- age 6: 10448408 bytes, 91378312 total
- age 7: 11724056 bytes, 103102368 total
- age 8: 12299528 bytes, 115401896 total
: 1807957K->147911K(1887488K), 0.1664510 secs] 5214984K->3554938K(6081792K) icms_dc=0 , 0.1671290 secs] [Times: user=0.61 sys=0.00, real=0.17 secs]
14251.429: [GC 14251.430: [ParNew
Desired survivor size 107347968 bytes, new threshold 7 (max 8)
- age 1: 25749296 bytes, 25749296 total
- age 2: 20111888 bytes, 45861184 total
- age 3: 7580776 bytes, 53441960 total
- age 4: 16819072 bytes, 70261032 total
- age 5: 13209968 bytes, 83471000 total
- age 6: 14088856 bytes, 97559856 total
- age 7: 10371160 bytes, 107931016 total
- age 8: 11426712 bytes, 119357728 total
: 1825735K->155304K(1887488K), 0.1888880 secs] 5232762K->3574222K(6081792K) icms_dc=0 , 0.1895340 secs] [Times: user=0.74 sys=0.06, real=0.19 secs]
14291.342: [GC 14291.343: [ParNew
Desired survivor size 107347968 bytes, new threshold 7 (max 8)
- age 1: 25786480 bytes, 25786480 total
- age 2: 21991848 bytes, 47778328 total
- age 3: 16650000 bytes, 64428328 total
- age 4: 7387368 bytes, 71815696 total
- age 5: 16777584 bytes, 88593280 total
- age 6: 13098856 bytes, 101692136 total
- age 7: 14029704 bytes, 115721840 total
: 1833128K->151603K(1887488K), 0.1941170 secs] 5252046K->3591384K(6081792K) icms_dc=0 , 0.1947390 secs] [Times: user=0.82 sys=0.04, real=0.20 secs]
14334.142: [GC 14334.143: [ParNew
Desired survivor size 107347968 bytes, new threshold 6 (max 8)
- age 1: 31541800 bytes, 31541800 total
- age 2: 20826888 bytes, 52368688 total
- age 3: 19155264 bytes, 71523952 total
- age 4: 16422240 bytes, 87946192 total
- age 5: 7235616 bytes, 95181808 total
- age 6: 16549000 bytes, 111730808 total
- age 7: 13026064 bytes, 124756872 total
: 1829427K->167467K(1887488K), 0.1890190 secs] 5269208K->3620753K(6081792K) icms_dc=0 , 0.1896630 secs] [Times: user=0.80 sys=0.03, real=0.19 secs]
14359.317: [Full GC 14359.317: [CMS: 3453285K->3099828K(4194304K), 13.1778420 secs] 4506618K->3099828K(6081792K), [CMS Perm : 261951K->181304K(264372K)] icms_dc=0 , 13.1786310 secs] [Times: user=13.15 sys=0.04, real=13.18 secs]
14373.287: [GC [1 CMS-initial-mark: 3099828K(4194304K)] 3100094K(6081792K), 0.0107380 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
14373.298: [CMS-concurrent-mark-start]
14472.579: [GC 14472.579: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 42849392 bytes, 42849392 total
: 1677824K->86719K(1887488K), 0.1056680 secs] 4777652K->3186547K(6081792K) icms_dc=0 , 0.1063280 secs] [Times: user=0.61 sys=0.00, real=0.11 secs]
14506.980: [GC 14506.980: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 42002904 bytes, 42002904 total
- age 2: 35733928 bytes, 77736832 total
: 1764543K->96136K(1887488K), 0.0982790 secs] 4864371K->3195964K(6081792K) icms_dc=0 , 0.0988960 secs] [Times: user=0.53 sys=0.01, real=0.10 secs]
14544.285: [GC 14544.286: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 26159736 bytes, 26159736 total
- age 2: 37842840 bytes, 64002576 total
- age 3: 33192784 bytes, 97195360 total
: 1773960K->130799K(1887488K), 0.1208590 secs] 4873788K->3230628K(6081792K) icms_dc=0 , 0.1215900 secs] [Times: user=0.59 sys=0.02, real=0.13 secs]
14589.266: [GC 14589.266: [ParNew
Desired survivor size 107347968 bytes, new threshold 4 (max 8)
- age 1: 28010360 bytes, 28010360 total
- age 2: 21136704 bytes, 49147064 total
- age 3: 35081376 bytes, 84228440 total
- age 4: 32468056 bytes, 116696496 total
: 1808623K->148284K(1887488K), 0.1423150 secs] 4908452K->3248112K(6081792K) icms_dc=0 , 0.1429440 secs] [Times: user=0.70 sys=0.02, real=0.14 secs]
14630.947: [GC 14630.947: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 28248240 bytes, 28248240 total
- age 2: 20712320 bytes, 48960560 total
- age 3: 18217168 bytes, 67177728 total
- age 4: 34834832 bytes, 102012560 total
: 1826108K->140347K(1887488K), 0.1784680 secs] 4925936K->3275469K(6081792K) icms_dc=0 , 0.1790920 secs] [Times: user=0.98 sys=0.03, real=0.18 secs]
14664.779: [GC 14664.779: [ParNew
Desired survivor size 107347968 bytes, new threshold 5 (max 8)
- age 1: 25841000 bytes, 25841000 total
- age 2: 22264960 bytes, 48105960 total
- age 3: 17730104 bytes, 65836064 total
- age 4: 17988048 bytes, 83824112 total
- age 5: 34739384 bytes, 118563496 total
: 1818171K->147603K(1887488K), 0.1714160 secs] 4953293K->3282725K(6081792K) icms_dc=0 , 0.1720530 secs] [Times: user=0.82 sys=0.11, real=0.17 secs]
14702.488: [GC 14702.489: [ParNew
Desired survivor size 107347968 bytes, new threshold 8 (max 8)
- age 1: 26887368 bytes, 26887368 total
- age 2: 21403352 bytes, 48290720 total
- age 3: 18732224 bytes, 67022944 total
- age 4: 17640576 bytes, 84663520 total
- age 5: 17942952 bytes, 102606472 total
: 1825427K->142695K(1887488K), 0.2118320 secs] 4960549K->3312168K(6081792K) icms_dc=0 , 0.2124630 secs] [Times: user=1.13 sys=0.14, real=0.21 secs]
我的目标是:我想限制Tenured的最小值,我正在服务请求并期望超过一定数量的共享对象,其他所有对象仅对手头的请求有用 . 因此,通过使用大的NewSize和增加的TenuringThreshold,并希望没有这些单个服务对象 .
以下是支持我的策略:
-Xms = 6G
-Xmx = 6G
-XX:NewSize = 2G //大空间,以免ParNew经常发生,让对象过期的时间到期
-XX:MaxTenuringThreshold = 8 //以限制更长时间
-XX:SurvivorRatio = 7 //基于示例-XX:CMSInitiatingOccupancyFraction = 60
//阻止促销分配导致的完整GC失败
-XX:UseCMSInitiatingOccupancyOnly
//根据示例使用上面的那个
MaxPermSize = 1G和“-Dsun.reflect.inflationThreshold = 0”与另一个我宁愿分开的问题有关 .
“-XX:CMSClassUnloadingEnabled”和“-XX:CMSPermGenSweepingEnabled”是因为grails严重依赖和额外的类关闭和反射
-XX:CMSIncrementalMode是一个没有取得多大成功的实验
5 回答
发布的日志片段显示您有大量的对象,这些对象的生存时间超过320秒(每个年轻集合大约40秒,并且在升级之前,对象可以通过8个集合生存) . 剩下的物体然后流入终身,最终你击中了一个显然意外的完整gc,实际上并没有收集太多 .
3453285K->3099828K(4194304K)
即你有一个4G终身,它被触发时大约82%(3453285/4194304),并且在13个长时间后大约74%满 .
这意味着需要13秒来收集~350M的总计,在6G堆的情况下并不是很多 .
这基本上意味着你的堆不够大,或者更可能是你有内存泄漏 . 这样的泄漏对于CMS来说是一件可怕的事情,因为并发终身收集是一个非紧凑的事件,这意味着终身是一个免费列表的集合,这意味着碎片可能是CMS的一个大问题,这意味着您对终身的利用变得越来越低效,意味着促销失败事件的可能性增加(尽管如果这是一个事件,那么我希望看到一条日志消息说明),因为它想要推广(或认为它需要推广)X MB到终身但它没有(连续的)空闲列表> = X MB可用 . 这会触发意外的终端收集,这是一个非远程并发的STW事件 . 如果你实际上有一点点收集(就像你那样)那么毫不奇怪你坐在你的拇指上 .
一些一般性的指示,在很大程度上重申弗拉基米尔·西特尼托夫所说的......
在多核盒子上使用iCMS是没有意义的(除非你有很多JVM或其他进程在那个盒子上运行,以至于JVM确实缺少CPU)因此删除了这个开关
你的年轻收藏品不必要地长,因为在每个收藏品的幸存者空间之间复制相对大量的记忆的影响,150-200ms是一个非常庞大的收藏品
ParNew
集合对年轻人问题的正确答案取决于分配行为的真正含义(例如,或许你最好拥有一个更大规模的新生代,并减少年轻的基因集合的频率,以便促进更少的对象,以便是最小的流失到终身) .
一些问题...
在此日志片段中,
正如其他人所指出的那样,你的巨大年轻一代和延长的任期似乎都不起作用 .
您应该分析您的应用程序并分析对象的年龄分布 . 我很确定Grails会将超出请求范围的各种事情进行缓存,这就是泄漏到旧版本的内容 .
你真正想要的是牺牲年轻一代的暂停时间(对于一个年轻的2GB)来推迟不可避免的 - 一个6GB的旧版本 . 这并不是你在那里做的一个很好的权衡 .
相反,你可能应该瞄准更好的年轻gen暂停时间,并允许CMS燃烧更多的CPU时间:更多的相位GC线程(不记得那个选项),更高的
GCTimeRatio
,MaxGCPauseMillis
>MaxGCMinorPauseMillis
来承受压力次要收藏并允许他们达到暂停目标,而不必调整大小以适应主要收藏限制 .为了减少主要GC的痛苦,您可能需要阅读:http://blog.ragozin.info/2012/03/secret-hotspot-option-improving-gc.html(此补丁应该在j7u4中) .
CMSParallelRemarkEnabled
也应该启用,不确定这是否是默认值 .替代方案:使用G1GC
就个人而言,我有一些可怕的经历,由于一些非常大的类似LRU的工作负载,G1GC正在进入一个角落,然后回归到一个大的,世界停止的集合,远远超过CMS在同一工作负载下遇到的并发模式故障 .
但是对于其他工作负载(比如你的工作负载),它实际上可以完成工作并逐步收集旧代,同时还可以压缩并避免任何大的暂停 .
如果你还没有试一试 . 再次,在你这样做之前更新到最新的java7,G1仍然有一些问题,他们试图解决它的启发式问题 .
编辑:自从我写完这个答案以来,Oracle已经改进了G1GC的启发式和一些瓶颈 . 现在绝对值得一试 .
另一种选择:吞吐量收集器
正如您在CMS中看到的那样 . 每当CMS遇到其中一种失败模式时,它都会执行 single-threaded ,世界各地的收集 .
请描述Tomcat可以使用多少CPU? 4?
你用的是什么java版本? (> 1.6.0u23?)
0)从Full GC输出,它看起来肯定你正在达到内存限制:即使在完全gc之后,仍有3099828K的已用内存(4194304K中) . 当你内存不足时,没有办法阻止Full GC .
3.1Gb工作集是否适合您的应用?那是3.1Gb的非垃圾内存!
如果这是预期的,是时候增加-Xmx / -Xms . 否则,是时候收集和分析堆转储以识别内存耗尽 .
解决3Gb工作集问题后,您可能会发现以下建议很有用:从我的角度来看,常规(非增量)CMS模式和减少NewSize值得尝试 .
1)当CMS线程将CPU产生到其他线程时,增量模式针对单个cpu机器 .
如果您有一些备用CPU(例如,您正在运行多核计算机),最好在后台执行GC而不会产生结果 .
因此,我建议删除-XX:CMSIncrementalMode .
2)-XX:CMSInitiatingOccupancyFraction = 60告诉CMS在OLD gen满60%后启动后台GC .
如果堆中有垃圾,并且CMS无法跟上它,那么降低CMSInitiatingOccupancyFraction是有意义的 . 例如,-XX:CMSInitiatingOccupancyFraction = 30,因此当旧的gen为30%时,CMS将启动并发收集 . 目前很难判断是否是这种情况,因为你在堆中没有垃圾 .
3)看起来“延长任期”并没有帮助 - 即使在7-8天之后,物体也不会消失 . 我建议减少SurvivorRatio(例如,SurvivorRatio = 2,或者只是删除选项并坚持默认) . 这将减少任期,从而减少次要gc暂停 .
4)-XX:NewSize = 2G . 你为NewSize尝试了较低的值吗?说,NewSize = 512m . 这应该可以减少次要的gc暂停,并使促销变得年轻 - >不那么大,简化了CMS的工作 .
你的幸存者数量并没有减少很多,如果有的话 - 理想情况下它们应该急剧下降,因为你只想让少数物体存活足够长的时间才能到达老一代 .
这表明许多物体生活的时间相对较长 - 其中例如,当您有许多未被快速处理的打开连接,线程等时,可能会发生这种情况 .
(您是否可以选择更改应用程序,或者只能修改GC设置?可能还有Tomcat设置会产生影响......)
下面是我对4核Linux盒的设置 .
根据我的经验,您可以调整-XX:NewSize -XX:MaxNewSize -XX:GCTimeRatio以实现高吞吐量和低延迟 .
-服务器
-Xms2048m
-Xmx2048m
-Dsun.rmi.dgc.client.gcInterval = 86400000
-Dsun.rmi.dgc.server.gcInterval = 86400000
-XX:AggressiveOpts
-XX:GCTimeRatio = 20
-XX:UseParNewGC
-XX:ParallelGCThreads = 4
-XX:CMSParallelRemarkEnabled
-XX:ParallelCMSThreads = 2
-XX:CMSScavengeBeforeRemark
-XX:UseConcMarkSweepGC
-XX:UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction = 50
-XX:新尺寸=512米
-XX:MaxNewSize =512米
-XX:PermSize =256米
-XX:MaxPermSize参数=256米
-XX:SurvivorRatio = 90
-XX:TargetSurvivorRatio = 90
-XX:MaxTenuringThreshold = 15
-XX:MaxGCMinorPauseMillis = 1
-XX:MaxGCPauseMillis = 5
-XX:PrintGCDateStamps
-XX:PrintGCDetails
-XX:PrintTenuringDistribution
-Xloggc:./日志/ gc.log