我的JVM内存泄漏在哪里?垃圾收集器工作正常吗?

时间:2014-04-15 14:24:26

标签: java scala memory-leaks garbage-collection jvm

我有一个Scala守护程序应用程序,它在Rackspace的服务器中运行,限制为2GB。由于原因不明,服务器在运行一段时间后就会卡住。我怀疑是否存在内存泄漏,因为服务器内存在一段时间后会变满。

我试图运行jvisualvm,在两个不同的时刻制作内存快照并比较它们以查看是否有分配的对象,但我找不到任何东西。

堆分配大约为400MB。以下是New Relic中的JVM内存快照:

enter image description here

请注意,PS Eden Space堆不断增加。我做了一个工作,每隔3个小时杀死一次应用程序并再次启动它(这就是为什么图形突然变回来了)。

为什么这个PS伊甸园正在增加?如何解决?

编辑1: 在13:00之前停止分钟的机器的屏幕截图 enter image description here

编辑2: 在新一轮中,左侧服务器自行挂起,并使用G1GC。这是此次运行的新遗物图: enter image description here

1 个答案:

答案 0 :(得分:3)

伊甸园不断增长是正常的,也就是分配新物品的地方。伊甸园将继续增长,直到它变满,或直到部分收集运行收集未使用的物体,并将正在使用的物体转移到幸存者区域S0。

这就像这种垃圾收集的设计方式一样。我们的想法是,Eden已经满了,我们让它成长,只有在最方便的时候才能收集它,最大限度地减少对应用程序代码的影响。

尝试删除变通方法,让服务器冻结并查看日志中是否存在任何内存不足错误。太多的类会导致这样的错误。

尝试查看OldGen是否已满。然后使用visualvm,强制进行垃圾收集,看看它是否已关闭。如果没有,则存在问题。

然后进行堆转储和线程转储并分析MAT - Eclipse Memory Analyser tool中的堆转储,也请参阅此tutorial。可能是服务器只需要更多内存。

一个重要的概念,在Java中实际上没有内存泄漏的概念,垃圾收集器大多完美无缺地收集未使用的对象。

通常问题来自于创建的对象,但是例如在静态集合或线程局部变量中意外地保留,并且因为它们被引用从未被收集。

具有免费试用版并允许生成精确报告的工具是Plumbr。这可能是快速解决方案的最佳机会,尝试运行plumbr以查看是否找到了某些内容,如果没有,那么堆转储的MAT分析。