Tomcat垃圾收集不彻底

时间:2017-03-24 12:49:33

标签: java tomcat memory garbage-collection

当我必须监视记忆时,我真的不在我的舒适区。但我是这里唯一的一个,而我只是一无所知:我在运行的Tomcat应用程序服务器上有一个Java8应用程序(CMS),并且遇到了麻烦。一段时间后,服务器崩溃了。

经过一番研究,我发现它与内存有关,所以我在我的环境中附加了visualVM,并开始监控。

我看到内存正在慢慢填满。垃圾收集是它的工作,但不是彻底。它总是在使用的堆中留下更多的内存。当我做手册'执行垃圾收集'在可视VM中,垃圾收集执行得更好。 (见截图)

Garbage collection performed by tomcat (first), Garbage performed manually (second downpeak)

它需要几个小时,但每次垃圾回收后,使用过的堆会再次变大和变大。我将再次手动预先形成GC的那一刻,最小的使用堆将是正常的'再次。

我注意到堆填充了byte []。这些将填补大部分空间。有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

  

我看到内存正在慢慢填满。垃圾收集呢   这是工作,但不彻底。它总是留下更多的记忆   用过的堆。当我在视觉上做一个手册'执行垃圾收集'   VM,垃圾收集执行得更好。

当JVM觉得它是必要的时候会触发完整的GC(因为它很昂贵。例如它停止了并行GC的世界。类似地停止世界的并发标记扫描收集器的两个子阶段)。它取决于各种因素,如Xms和Xmx参数,请参阅JVM heap parameters。所以你不应该担心,除非你因为JVM在必要时触发而忘记了mem异常

对于服务器崩溃: - 我可以想到两个问题

  1. 内存泄漏。在这种情况下,即使在每个GC
  2. 之后,内存占用量也会增加
  3. 如果它接近完整
  4. ,你可能正在构建一些没有逐出算法的缓存

    如果两者都不适用,我会看到增加堆的用例并试一试

答案 1 :(得分:1)

我以前遇到过这样的问题。一个是我们的应用程序的错,一个是应用程序服务器的错,一个我无法弄清楚但能够缓解。

在每种情况下,我使用JProfiler来观察本地服务器上的内存使用情况,并运行各种快乐路径和异常测试,以试图找出导致问题的原因。做这个测试不是一个快速简单的过程 - 平均每次我花了大约一个星期。

在第一种情况下(我们的应用程序的错误),我发现在抛出异常时我们没有关闭Web服务的SQL连接。测试快乐路径没有问题,但是当我开始测试异常时,我可能会耗尽大约100个连续异常来耗尽服务器的内存。添加代码以手动清理异常处理程序中的资源解决了这个问题。

在第二种情况下(WebSphere的错误),我验证了我们的应用正在关闭所有资源,但问题仍然存在。所以我开始阅读WebSphere文档,发现这是JAX-WS客户端的一个已知问题。幸运的是,WebSphere有一个补丁修复了这个问题。

在第三种情况下(无法确定原因),我无法找到任何原因。因此,通过将JVM内存分配增加到OOM异常将花费超过1周的时间并将服务器配置为每周末重新启动来缓解问题。

答案 2 :(得分:0)

可能会有一些简单的技术解决方法来缓解这个问题;喜欢:简单地向JVM和/或底层机器添加更多内存。

或者,如果您真的可以证明手动运行function updateTime() { //You rest of code } setInterval(updateTime, 500); 有帮助(因为评论表明大多数人都认为:它不会),您可以自动执行该步骤。

如果其中任何一个足以防止那些崩溃;您正在为自己花费更多时间来使用真正的解决方案。

除此之外,还有一个非技术性的元视角。实际上有两种选择:

  • 你转向你的经理;而且你告诉他你需要在2,4,8周之间做任何事情才能学习这些东西;这样你就可以确定根本原因并修复它。
  • 你转向你的经理;而且你告诉他他应该寻找一些外部咨询服务,找出根本原因并帮助修复它。

换句话说:您的团队/产品需要一些“专家”知识。要么你投资于在内部建立知识;或者你必须从某个地方购买它。