如何获取Java8的Metaspace转储(而不是堆转储)

25

有没有工具可以从Java8热点虚拟机中获取Metaspace dump?


3
您希望以何种形式获取这些数据,需要用于什么目的?请注意,Metaspace中的数据不是Java对象。也许您对HotSpot内部结构不感兴趣,而是对其他内容感兴趣。 - apangin
3
我们的应用程序导致Metaspace OOM错误,设置了1G的MaxMetaspaceSize,我想知道Metaspace内存的使用情况。 - czh
2个回答

29

看起来你遇到了类加载泄漏问题。
使用

  • jmap -clstats PID 命令来转储类加载器统计信息;
  • jcmd PID GC.class_stats 命令则会打印每个加载的类的内存使用情况的详细信息。后者需要 -XX:+UnlockDiagnosticVMOptions 参数。

堆转储也有帮助,因为Metaspace中的每个类都对应着堆中的一个 java.lang.Class 实例。


嗨apangin,谢谢你的建议。我已经能够使用jmap -dump命令转储整个堆了,但是我正在努力运行jhat命令来分析转储文件。堆转储大约有5GB大小,而jhat已经运行了2个小时而没有完成,这正常吗? - czh
jhat在运行约2小时后最终以堆空间OOM错误终止。 - czh
1
@czh Eclipse Memory Analyzer即使处理大型堆转储文件也表现良好。 - apangin
@czh 你也可以尝试使用VisualVM或YourKit来处理更大的堆。 - Peter Lawrey
1
如何解读以下统计数据以了解我的METASPACE OOM修复是否有效?转储原因:JCMD MaxMetaspaceSize:536870912 B CompressedClassSpaceSize:528482304 B 类空间已使用:21412264 B 类空间容量:25373696 B 类空间已提交:44572672 B 类空间已保留:1073741824 B 非类空间已使用:178477376 B 非类空间容量:219028480 B 非类空间已提交:347594752 B 非类空间已保留:348127232 B - machinarium
我曾经苦于确定我的项目中是什么导致了元空间泄漏。我使用 jcmd PID GC.class_stats 来识别常驻类,然后使用堆转储 + VisualVM 来确定是什么(哪个 GC 根)在保留这些不需要的类。 - SP193

0
如果您想深入了解元空间分配情况,更详细的选项是使用本地内存跟踪。您需要使用详细级别的本地内存跟踪,可以通过将-XX:NativeMemoryTracking=detail传递给JVM来启用。然后您可以运行。
jcmd <pid> VM.native_memory baseline

建立一个基准。然后在让JVM运行直到问题再次出现后,您可以运行

jcmd <pid> VM.native_memory detail.diff

然后,NMT diff中的Class分配将提供元空间分配。 orcale docs上有关于NMT的更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接