为什么这些Tomcat服务器的JVM每小时执行一次完整的GC?

2022-09-01 13:19:30

我们运行许多Tomcat服务器,并观察到完全垃圾回收(GC)通常每小时执行一次,特别是当内存使用率相对较低时。确切的时间似乎是相对于应用程序服务器启动的时间而言的。如果服务器在 01:13 启动,则完整的 GC 在 02:13 完成,下一个完整的 GC 将在 03:13 发生。我无法找到任何文档来解释此行为。

这是一个问题,因为同时启动的服务器池往往会同时执行完整的 GC。如果 GC 延迟足够长,导致负载平衡器将服务器标记为关闭,则整个应用程序可以在一段时间内脱机。如果完整的GC可以分布在一段时间内,这样就不会有两台服务器同时执行完整的GC,那会更好,但我找不到任何方法来控制这种行为。

有没有人见过这种行为?有没有办法影响这些“常规”完整指导性案例何时发生?


答案 1

您的“常规”每小时 GC 可能是由于这个已知的错误,“当 gcDaemonProtection=true 时,JreMemoryLeakPreventionListener 每小时都会导致一个完整的 GC”。

确认您的 Tomcat 版本和您的属性的值(默认值为 )。gcDaemonProtectionJreMemoryLeakPreventionListenertrue

据称,该补丁包含在Tomcat v.7.0.28 +和v.6.0.36 +中。

升级服务器,或从此处选择非升级解决方案,总结如下:

  1. 使用 JVM arg 禁止完全垃圾回收-XX:+DisableExplicitGC
  2. 保留完整的 GC,但遵从使用 JVM 参数的 CMS 收集器-XX:+ExplicitGCInvokesConcurrent
  3. 设置<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" gcDaemonProtection="false"/>
  4. 禁用侦听器

应得信贷的信贷;我从这里得到了我最初的答案。


答案 2

您应该能够通过以下方式更改间隔

-Dsun.rmi.dgc.client.gcInterval=60000
-Dsun.rmi.dgc.server.gcInterval=60000

看看这里 https://docs.oracle.com/cd/E19199-01/817-2180-10/pt_chap5.html