JProfiler:试图找到内存泄漏

时间:2013-02-19 09:33:43

标签: jprofiler

我的应用程序需要大约10 GB的RAM用于特定输入,其中常规输入大约1 GByte就足够了。使用JProfiler进行更密切的分析表明(在GC之后)java.util.*的标准类使用了相当多的内存:

LinkedHashMap$EntryHashMap$Entry[]LinkedHashMapHashMap$KeySetHashMap$EntrySetLinkedHashSetTreeMap$Entry和{{1} (按此顺序)和相关的类。以下条目是我自己的代码中的一个类,其中实例的数量和使用的内存量似乎非常合理。

详细说明总堆使用量约为900 MB,我在TreeMap视图中看到以下Size条目:

  • All Objects:418 MByte
  • LinkedHashMap$Entry:178 MByte
  • HashMap$Entry[]:124 MByte
  • LinkedHashMap:15 MByte

HashMap$KeySet使用的内存似乎过高,即使考虑到每个LinkedHashMap都有LinkedHashSet支持。

我在JProfiler中记录了对象分配,并观察LinkedHashMap Allocation Hot Spots。在那里,我看到了我不理解的条目:

  • 第三个条目显示了一个名为LinkedHashMap的热点(已分配内存的6.5%),其中X.<init>是我自己代码中的一个类。此方法的构造函数与X无关。在LinkedHashMap结尾处输入后,Thread.run显示从6.5%缓慢下降到5.8%。我的代码在Thread.run中可能出现什么问题?为什么会在这里显示?
  • 大约8%的已分配内存显示在名为X的热点中。沿着具有最高百分比(第一个条目:2.8%)的路径进入此条目之后,我在代码中获得了几个方法,直到最后显示java.util.HashSet.iterator(具有2.8%)。这是什么意思?据我所知,java.lang.Thread.run方法不会创建Thread.run的实例。与LinkedHashMap方法的连接是什么?

一般来说,如何找到引用(很多)iterator个对象的代码?使用Heap Walker我只能看到那些实例的 lot ,但看不到任何模式(即使在观察GC根路径时)。在我的实验中,所有实例似乎都是有序的。

可能很重要的事情:

  • 我的应用程序构造一个结果(用于进一步处理),并且对于这种结构,观察到高内存使用。构造不断创建对象,因此等待稳定点然后观察每个创建的LinkedHashMap对象是不可能的。
  • 我有很好的计算机可供调试(最多48个内核和192 GB内存,甚至可能更多)。
  • java version“1.7.0_13”(Java(TM)SE Runtime Environment(build 1.7.0_13-b20), Java HotSpot(TM)64位服务器VM(版本23.7-b01,混合模式))
  • JProfiler 7.2.2(Build 7157),已获得许可

1 个答案:

答案 0 :(得分:5)

  

一般来说,如何找到引用(很多)LinkedHashMap对象的代码?

在堆沃克中,选择&#34; LinkedHashMap&#34;并创建一个新的对象集。然后切换到&#34;参考&#34;查看并显示&#34;累计传入参考&#34; 。在那里,您可以分析整个对象集的引用。

enter image description here

关于分配热点以及为什么显示Thread.run方法的问题:这些是后退跟踪,它们显示了如何调用热点以及节点上的所有数字都是对顶部热点的贡献。最深的节点将始终是一个入口点,通常是Thread.run方法或主方法。