tomcat 周期性无响应

tomcat 周期性无响应

我在我们的生产环境中遇到了 Tomcat 周期性无响应的情况。我无法在测试环境中重现此情况,并且在事件发生之前或期间日志中没有任何内容。Tomcat 继续运行,但停止处理请求。我已阅读此主题并将垃圾收集输出选项放在 JAVA_OPTS 中,尽管我尚未重新启动 tomcat 以使它们生效。我的情况不同,因为 tomcat/jvm 显然不会恢复或“唤醒”。我已确认我们的应用程序多次至少 15 分钟没有响应。解决方案始终是重新启动 tomcat(使用 daemontools)。频率各不相同,有时在高峰负载期间,有时在半夜(负载非常轻)。

我已为 jvm 允许最多 4g 内存(-Xms2g -Xmx4g)。服务器有 16g 内存,正在运行 64 位 jvm。 Sun 的白皮书关于 Java 调优的说法:“在垃圾收集操作期间,投入过多的系统物理内存可能会导致虚拟内存分页到磁盘,从而导致严重的性能问题。”我是否将堆大小设置得太大了?将最小大小设置为与最大值相同是否有益?

我不认为系统正在将内存交换到磁盘。 free -m 的输出显示没有交换使用,并且我在系统上将 swappiness 设置为 0。

当今天凌晨 2:30 出现无响应时,我在重新启动 tomcat 之前快速运行了 jstat 和 ps:

jstat 显示的值与现在相似,但有一些例外:YGC 为 431,现在为 44,YGCT 为 10/1,FGC 为 59/7,FGCT 为 39/2,GCT 为 49/3

ps 的输出显示常驻内存使用量为 1422832,虚拟内存使用量为 5723580。相比之下,昨天正常运行时,常驻内存使用量为 1390036,虚拟内存使用量为 5642668。

我不是这方面的专家,因此如果能得到任何帮助我都会很感激。


更新:好的,我已将以下内容添加到 JAVA_OPTS 并将立即重新启动 tomcat:

-XX:+UseConcMarkSweepGC -Xms2g -Xmx2g -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails

变化包括:1) 切换 gc 算法。2) 降低最大堆大小,因为看起来我不需要 4g,而且显然过度使用会导致周期性大量 gc。3) 打开 vebose gc 日志记录。谢谢大家。

答案1

首先,这里有一个有用的链接“使用 5.0 Java TM 虚拟机调整垃圾收集”

这听起来确实像是 GC 暂停导致 tomcat 不响应。首先要使用带有选项的“低暂停”垃圾收集器-XX:+UseConcMarkSweepGC

答案2

我们在生产环境中多次看到这种情况,最终是 Java 的垃圾收集停止了进一步的请求。对我们来说最大的问题是,在无响应期间,至少一个核心的处理器使用率为 100%。

在我们的案例中,答案是追踪应用程序中的内存泄漏。我不确定这对你来说算不算答案,但至少是另一个数据点。

相关内容