我有一个 Scala 守护程序应用程序,它在 Rackspace 中的服务器中运行,限制为 2GB。由于未知原因,服务器在应用程序运行一段时间后卡住。我怀疑存在内存泄漏,因为一段时间后服务器内存已满。
我尝试运行 jvisualvm,在两个不同的时刻制作内存快照并比较它们以查看是否有仍然分配的对象,但我找不到任何东西。
堆分配大小约为 400MB。以下是 New Relic 中 JVM 内存的快照:
请注意,PS Eden Space 堆不断增加。我做了一个解决办法,每 3 小时终止应用程序并再次启动它(这就是图表突然下降的原因)。
知道为什么这个 PS Eden 正在增加吗?如何解决?
编辑 1: 13:00 前几分钟停止的机器截图
编辑 2: 在新一轮中,a 导致服务器挂起,并使用了 G1GC。这是本次运行的新遗迹图:
最佳答案
伊甸园不断增长是正常的,这是分配新对象的地方。 Eden 将继续增长,直到填满或直到运行部分收集来收集未使用的对象,并将正在使用的对象转移到幸存者区域 S0。
这是按照此类垃圾收集的设计方式。我们的想法是,Eden 已满也没关系,我们让它增长并仅在最方便的时候进行垃圾收集,从而最大限度地减少对应用程序代码的影响。
尝试删除解决方法,让服务器卡住并查看日志中是否存在内存不足错误。太多的类会导致此类错误。
尝试查看 OldGen 是否已满。然后使用 VisualVM,强制进行垃圾回收,看看它是否会崩溃。如果没有,那就有问题了。
然后进行堆转储和线程转储并分析 MAT - Eclipse Memory Analyser tool 中的堆转储,请参阅此 tutorial以及。可能是服务器需要更多内存。
一个重要的概念,在 Java 中实际上不存在内存泄漏的概念,垃圾收集器几乎可以完美地收集未使用的对象。
通常,问题来自于创建的对象,但意外地保留在静态集合或线程局部变量中,并且因为它们被引用而从未被收集。
Plumbr 是一个可以免费试用并可以生成报告来查明许多常见原因的工具。 。这可能是快速解决方案的最佳机会,尝试运行plumbr以查看它是否找到了某些东西,如果没有,则对堆转储进行MAT分析。
关于java - 我的 JVM 内存泄漏在哪里?垃圾收集器工作正常吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23086595/