Tomcat CPU和GC疯了

我们的Tomcat 7安装有一些主要问题。 它曾经运行良好超过一年,但现在的CPU主要是在400% – 700%(8芯机),在日志中我看到这些音调:

2015-04-01T23:05:13.046+0200: 5177.229: [GC2015-04-01T23:05:13.046+0200: 5177.229: [ParNew: 1398632K->345K(1747648K), 0.0062240 secs] 3439622K->2041335K(5941952K) icms_dc=0 , 0.0063310 secs] [Times: user=0.04 sys=0.00, real=0.00 secs] 

我的Tomcat启动设置(在setenv.sh中)是:

 CATALINA_OPTS="$CATALINA_OPTS -server -Xms6G -Xmx6G -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:NewRatio=2 -XX:SurvivorRatio=4 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Djava.awt.headless=true -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -Djava.security.egd=file:/dev/./urandom" 

行为通常是这样的机器运行一个小时左右,我看到它消耗内存,然后开始尝试GC,我每秒得到这些日志条目。

我已经尝试了不同的GC设置,并没有成功。 正如刚刚发生的那样,我不知道这可能是什么原因,或者如果有人在这里有一个解决scheme?

我的服务器有Ubuntu LTS 14.04.2和Oracle Java 7的32GB内存。

GC打开日志,看起来GC工作正常。

  [ParNew: 1398632K->345K(1747648K), 0.0062240 secs] 

表示在小于百分之一秒的时间内清理了大约1.2 GB的新对象。 如果这种情况每秒发生一次,应用程序正在创build很多短暂的对象。 检查时间戳,看看发生的频率。 我通常瞄准几秒钟(新一代GC循环之间的时间为10秒或更长时间),但是没有提供足够的数据来进行大量的分析,并发的GC循环通常每小时发生一次,日志消息。

为GC数据指定单独的日志文件通常很有帮助。 这使得审查更容易。 您可以指定该日志在达到一定大小后进行旋转。 试试这些选项-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=100M ,如果你没有单独的日志添加-Xloggc:logs/gc.log

有了这么大的新一代,并发GC可能需要很长时间才能运行。 添加-XX:+ScavengeBeforeFullGC将使新一代在开始时被清除,并应该改进GC调优。

查看有关垃圾收集的文档,以更好地理解正在发生的事情。