3

我试图在我的 java 应用程序中找到内存泄漏的原因。我需要为处于GC 周期中的进程获取堆转储。Jmap 在这种情况下不起作用,因为应用程序被挂起并且因为堆非常大。

不幸的是,jmap 在我使用的核心转储中抛出了 UnknownOopException。我想在 GC 期间进行核心转储是不正确的。有什么方法可以在正确进行核心转储时暂停 java 进程?

还是我完全错了并且由于其他问题而损坏了核心转储?

4

3 回答 3

2

在执行 GC 时不能进行堆转储。您需要在 GC 之前或之后进行堆转储。如果您想知道为什么要花这么长时间,那么确定哪个 pahse 需要这么长时间是很有用的。要查看此添加-verbosegc 这将指示是否需要很长时间才能到达安全点、复制对象、扫描永久空间、检查引用或其他内容。

这可能需要一些时间,因为您有很多对象要清理。作为一种猜测,最坏的情况下每 2 GB 堆对象可能需要 1 秒。

于 2012-12-18T14:05:41.473 回答
0

您需要做的是在堆接近满以致 GC 锁定应用程序之前进行堆转储。

于 2012-12-18T14:04:13.133 回答
0

根据我的经验,OutOfMemory 异常或长 GC 周期并不一定表示内存泄漏。

为了搜索内存泄漏,需要间隔一段时间进行 2 个单独的堆转储(我使用过 jvisualvm,现在一个版本与 JDK 捆绑在一起)并分析它们。提示:检查对象的保留大小会有所帮助。

根据您的应用程序所做的事情以及如果没有出现明显的内存泄漏,调整 JVM GC 选项是您最好的选择。寻找世代比率,新对象被终身使用后的世代等。

希望这个对你有帮助。

于 2012-12-18T14:06:01.523 回答