全 GC 变得非常频繁

2022-09-04 20:12:20

我有一个Java webapp在一个tomcat实例上运行。在高峰时段,Web应用程序每秒提供约30页,通常约为15页。

我的环境是:

O/S: SUSE Linux Enterprise Server 10 (x86_64)
RAM: 16GB

server: Tomcat 6.0.20
JVM: Java HotSpot(TM) 64-Bit Server VM 1.6.0_14
JVM options:
CATALINA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m
               -XX:+UseParallelGC
               -Djava.awt.headless=true
               -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
JAVA_OPTS="-server"

经过几天的正常运行时间后,完整的GC开始更频繁地发生,这成为应用程序可用性的严重问题。在tomcat重新启动后,问题消失了,但当然,在5到10或30天后会返回(不一致)。

重新启动之前和之后的完整 GC 日志处于 http://pastebin.com/raw.php?i=4NtkNXmi

它显示了重新启动之前的日志,即6.6天的正常运行时间,其中应用程序正在遭受损失,因为Full GC需要2.5秒,并且每约6秒发生一次。

然后,它会在重新启动后显示一个日志,其中 Full GC 每 5-10 分钟才发生一次。

我有两个转储使用,当发生完整的GC时(我不确定当一个完整的GC发生时或2个完整的GC之间,我是否得到了完全正确的转储),并在 http://www.eclipse.org/mat/ 打开它们,但在泄漏嫌疑人中没有得到任何有用的东西:jmap -dump:format=b,file=dump.hprof PID

  • 60MB:1个“org.hibernate.impl.SessionFactoryImpl”的实例(我使用hibernate with ehcache)
  • 80MB:1,024个“org.apache.tomcat.util.threads.ThreadWithAttributes”的实例(这些可能是tomcat的1024个工人)
  • 45MB:37个“net.sf.ehcache.store.compound.impl.MemoryOnlyStore”的实例(这些应该是我在ehcache中的约37个缓存区域)

请注意,我永远不会得到一个超出记忆的错误。

关于我下一步应该去哪里看的任何想法?


答案 1

当我们遇到这个问题时,我们最终将其追踪到年轻一代太小了。虽然我们给了很多公羊,但年轻一代没有得到公平的份额。

这意味着小型垃圾回收将更频繁地发生,并导致一些年轻对象被移动到终身一代中,这意味着更多的大型垃圾回收也是如此。

尝试使用具有相当低的值(例如2或3),看看这是否有帮助。-XX:NewRatio

更多信息可以在这里找到。


答案 2

我已经从 切换到 了 问题就消失了。我现在有100天的正常运行时间。-Xmx1024m-Xmx2048m


推荐