JProfiler:试图找到内存泄漏

C-O*_*tto 3 jprofiler

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

LinkedHashMap$Entry,HashMap$Entry[],LinkedHashMap,HashMap$KeySet,HashMap$EntrySet,LinkedHashSet,TreeMap$Entry,和TreeMap(以该顺序),和相关的类.以下条目是我自己的代码中的一个类,其中实例的数量和使用的内存量似乎非常合理.

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

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

使用的内存LinkedHashMap似乎太高,即使考虑到每个LinkedHashSet都由a支持LinkedHashMap.

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

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

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

可能很重要的事情:

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

Ing*_*gel 5

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

在堆walker中,选择"LinkedHashMap"并创建一个新的对象集.然后切换到"参考"视图并显示"累计传入参考".在那里,您可以分析整个对象集的引用.

在此输入图像描述

至于你关于分配热点的问题以及Thread.run方法显示的原因:这些是回溯迹,它们显示了如何调用热点,节点上的所有数字都是对顶部热点的贡献.最深的节点将始终是入口点,通常是Thread.run方法或main方法.