我有一个Java程序,经过16个小时左右的时间,慢慢地用整数组填满了堆,而GC却没有摆脱。
我只有VisualVM可用来诊断这个问题,这才发现是 int[]
填充在堆中。
有什么办法能让我找到这个文件的来源吗?int[]
创建?
我是使用剖析器的新手,所以可能我错过了这个功能,但我用它的堆转储、快照和剖析器看了一下,它告诉我的只是 int[]
是在大量使用。
在VisualVM中,你可以找到对象的引用。这应该能给你一个线索,让你知道你的程序是哪一部分泄露了那些int数组。
说明:让你的程序运行很长时间。
让你的程序运行很长时间 这样你就能在堆上找到很多泄露的int数组实例了。
在VisualVM中做一个堆转储。主菜单 > 应用程序 > 堆转储 (Heap Dump). 一个堆转储选项卡应打开。
在堆转储选项卡中,单击 概要 字段,并将其改为 对象. 应打开堆对象类型的列表。
展开 int[]
条目以查看实例列表。
展开其中一个实例。
展开 参考文献 条目。
将打开一个引用该int数组实例的字段列表。这里的信息可能会给你一个线索。
对不同的实例重复第5-6步,直到找到其中一个泄露的数组。
下图显示了我的Eclipse的堆转储中对一个int数组的引用。
在这个例子中,int数组实例存储在 valueTable
领域的一些内部Eclipse OffsetTable
类,而该类又被一个 RegistryObjectManager
.
jmap
,用命令提取内存转储。jmap -dump:live,format=b,file=dumplive.hprof <PID>
hprof
归入 Eclipse内存分析器(MAT).注 可以作为插件安装在Eclipse安装中,但如果转储太大,我不推荐。
通过分析器,你可以看到捕获瞬间的所有内存使用信息。