我们的程序之一有时会在一个用户的计算机上出现OutOfMemory
错误,但是当我测试它时当然不会。我只是使用JProfiler(因为我从未使用过它,所以使用了10天的评估许可证)运行它,并过滤了我们的代码前缀,所以在总大小和实例数上最大的块是8000+个特定简单类的实例。
我单击了JProfiler上的“垃圾收集”按钮,大多数其他类的实例都消失了,但是这些特殊的实例却没有。我仍然在同一实例中再次运行测试,它创建了该类的4000多个实例,但是当我单击“垃圾收集”时,那些实例消失了,剩下了8000多个原始实例。
这些实例确实在各个阶段陷入了各种Collection中。我假设它们不是垃圾收集的事实,这意味着某些内容正在保留对集合之一的引用,从而保留了对对象的引用。
关于如何找出引用的任何建议?我正在寻找有关在代码中查找内容的建议,以及在JProfiler中找到此内容的方法。
最佳答案
转储并检查堆。
我敢肯定有多种方法可以做到这一点,但这是一个简单的方法。此说明适用于MS Windows,但是可以在其他操作系统上执行类似的步骤。
这是一个例子:
C:\dump>jmap -dump:format=b,file=heap.bin 3552
C:\dump>jhat heap.bin
Reading from heap.bin...
Dump file created Tue Sep 30 19:46:23 BST 2008
Snapshot read, resolving...
Resolving 35484 objects...
Chasing references, expect 7 dots.......
Eliminating duplicate references.......
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
为了解释这一点,了解Java的array type nomenclature的使用很有用-例如知道类[Ljava.lang.Object; 实际上是指 Object [] 类型的对象。