Java 如果应用程序在GC中,如何可靠地获取JVM核心转储?

Java 如果应用程序在GC中,如何可靠地获取JVM核心转储?,java,linux,coredump,Java,Linux,Coredump,我试图找出java应用程序内存泄漏的原因。我需要为处于longGC周期的进程获取堆转储。Jmap在这种情况下不起作用,因为应用程序被挂起,堆非常大 不幸的是,jmap在我获取的核心转储上抛出了UnknowNoopeException。我认为在GC期间进行核心转储是不正确的。是否有任何方法可以在获取核心转储正确时暂停java进程 还是我完全错了,因为其他问题而导致核心转储中断?您需要做的是在堆接近满之前进行堆转储,以防GC锁定应用程序。执行GC时无法进行堆转储。您需要在GC之前或之后进行堆转储。如

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

不幸的是,jmap在我获取的核心转储上抛出了UnknowNoopeException。我认为在GC期间进行核心转储是不正确的。是否有任何方法可以在获取核心转储正确时暂停java进程


还是我完全错了,因为其他问题而导致核心转储中断?

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

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


这可能需要很长时间,因为你有很多东西要清理。作为猜测,最坏的情况可能是每2GB堆对象需要1秒。

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

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

根据您的应用程序所做的工作以及如果没有出现明显的内存泄漏,调整JVM GC选项是最佳选择。查找生成比率、新对象终身使用后的生成数等


希望这能有所帮助。

即使我在GC锁定应用程序之前获得了核心转储,我也不能确定核心转储是否一致。我想你可以。我的理解是,当堆被转储时,JVM会挂起所有线程。当直接在JVM进程上使用jmap时,可能会挂起所有线程。但是jmap在巨大堆上的性能非常差,所以我不得不使用gcore。不幸的是,不可能在安全点强制挂起JVM来安全地进行核心转储?对于来这里的人来说:实际上,我看到在使用30 GB堆的CMS时,每2 GB堆对象的1秒比1秒差得多(它可能需要几分钟才能生存)。@pickypg你是对的,根据你的使用情况,你可能会得到更糟糕的计时。例如,你有很多从老一代到新一代的参考资料,很多参考资料,或者很多Finalize()可设置对象。如果您避免使用速度较慢的功能,但在80 GB堆的最坏情况下,您可以获得4秒的暂停时间(我正在尝试调整的应用;)