【问题标题】:JProfiler: Trying to find memory leakJProfiler:试图找到内存泄漏
【发布时间】:2013-02-19 09:33:43
【问题描述】:

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

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

在总堆使用量约为 900 MByte 的情况下,我在 All Objects 视图中看到以下 Size 条目:

  • LinkedHashMap$Entry: 418 兆字节
  • HashMap$Entry[]: 178 兆字节
  • LinkedHashMap: 124 兆字节
  • HashMap$KeySet:15 兆字节

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

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

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

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

可能重要的事情:

  • 我的应用程序构造了一个结果(用于进一步处理),并且对于此构造,观察到高内存使用率。该构造不断创建对象,因此不可能等待一个稳定点然后观察每个创建的 LinkedHashMap 对象。
  • 我有很好的计算机可供调试(最多 48 个内核和 192 GB RAM,可能更多)。
  • java 版本 "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(内部版本 7157),许可

【问题讨论】:

    标签: jprofiler


    【解决方案1】:

    一般来说,我如何找到保留对(大量)LinkedHashMap 对象的引用的代码?

    在堆遍历器中,选择“LinkedHashMap”并创建一个新的对象集。然后切换到“引用”视图并显示“累积传入引用”。在那里,您可以分析整个对象集的引用。

    关于分配热点以及为什么显示 Thread.run 方法的问题:这些是回溯,它们显示了热点是如何被调用的,并且节点上的所有数字都是对热点的贡献居高不下。最深的节点将一直是入口点,通常是 Thread.run 方法或 main 方法。

    【讨论】:

    • 这当然有帮助,我不知何故忽略了累积的视图...感谢您的提示!关于回溯:这是否意味着所创建实例的 5.8% 和 2.8%(基于我的数字)是由调用 Thread.run 方法的代码创建的?或者,换句话说,我是否必须沿着回溯寻找使百分比发生显着变化(例如,从 1% 跃升至 4%)的方法?
    • 不,所有这些都是在热点中创建的,而在回溯节点中什么都没有。可以使用不同的调用堆栈调用热点,并且回溯会解析此信息,即回溯节点上的数字仅显示沿该特定调用堆栈贡献的部分。
    • 谢谢,我现在明白了。
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 2012-04-04
    • 2018-04-07
    • 1970-01-01
    相关资源
    最近更新 更多