2012-07-26 109 views
2

我最近做了一个hprof格式的heapdump,当我的jboss服务器运行时,xms为4096m,xmx为4096m,数据大小为512m。堆转储大小vs hprof大小

生成的hprof文件大于5GB。当我在visualvm,mat分析器或yourkit中加载heapdump时,我只能看到大约1GB的总字节数。我已经尝试在yourkit中更改可达范围,但它不会显示超过1 GB的值。

任何想法文件大小与显示的堆转储大小可能导致这种巨大差异?

PS:我使用的是jdk1.6.0_23

可惜我不能在这里提交截图。

在文件系统中的HPROF大小是5.227.659 kb和在yourkit它指出:其中740 MB字符串可达:

对象:9.738.282 /浅尺寸740 MB /保留大小6.652.515 (68%)/尺寸浅:381 MB(51%)/保留大小:381 MB(51%)

最大保留大小是字节[]的206.810.176你使用哪个命令

+0

你可以发布VisualVM中'Summary'选项卡的屏幕截图吗? – 2012-07-26 13:49:22

+0

我无法添加屏幕截图,但我确实添加了来自yourkit的信息 – Michael 2012-07-27 07:18:25

+0

来自YourKit的数据并不能帮助我 - 我不知道它们是如何计算的。我知道这是如何在VisualVM中完成的。如果您希望我帮助您,请提供“基本信息”部分的数据(复制位于上下文菜单中),或者您可以将压缩堆转储上传到某处并将链接发送给我。 – 2012-07-27 15:05:38

回答

2

生成堆转储?

$JAVA_HOME/bin/jmap -dump:live,format=b,file=c:/tmp/heap_dump.bin PID 

也许你需要通过现场选项,根据规范

-dump:<dump-options> to dump java heap in hprof binary format 
        dump-options: 
        live   dump only live objects; if not specified, 
            all objects in the heap are dumped. 
+0

嗨,我们使用以下命令:jmap -F -dump:format = b,file = $ {filename} $ PID。根据oracle的实时选项:“如果指定,只有堆中的活动对象被转储。”所以,如果我指定这个,堆转储最可能会更小,但也可能会减少我找到内存泄漏的原因 – Michael 2012-07-26 10:50:44

+0

这真的是一个很好的问题 - 什么是活的对象?我假设活体对象是不可用于GC的东西。所以我猜活的选择将只是删除垃圾对象,你将只有活的对象 - 这并不意味着这减少了发现的机会...我最近发现真正巨大的转储(大约16 GB)的实时选项内存泄漏很少, ... – 2012-07-26 11:02:21

+0

嗨安德烈,谢谢你的回应。 “我最近在真正巨大的转储(大约16GB)中发现了很多内存泄漏,”我可以想象它可能会有所帮助,但它仍然没有意义,为什么磁盘上的hprof大小与当我在这些工具中加载hprof(heapdump)时,分析工具显示的大小...... – Michael 2012-07-26 11:54:50

2

你尝试“不可达的对象直方图”(你可以找到“概述”页面顶部的链接)?在我的一个大小为1509MB的堆栈中,mat只显示了454MB,但其余的基本上都是垃圾,确实,无法访问的对象直方图中的“Shallow Heap”总和为966MB。

1

这只是意味着,如果GC要运行,那么很可能您的堆转储包含大量无法访问的对象,这些对象会被垃圾收集。 现在这并不意味着你仍然没有泄漏,只是意味着在你的5 GB Hprof中,4 GB的对象是无法访问的,因此不是有趣的泄漏源。

在Java中,只有当垃圾收集无法清除某个对象时才会发生内存泄漏,因为某些对象持有引用(意外)。所以你的泄漏(如果有的话)将被发现在你的hprof中剩下的1GB物体中。