代码之家  ›  专栏  ›  技术社区  ›  C-Otto

JProfiler:试图查找内存泄漏

  •  3
  • C-Otto  · 技术社区  · 12 年前

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

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

    对于大约900 MB的总堆使用量,我看到了以下内容 Size 中的条目 All Objects 视图:

    • 链接的哈希映射$Entry :418 MB
    • 哈希映射$Entry[] :178 MB
    • 链接的哈希映射 :124 MB
    • 哈希映射$KeySet :1500万字节

    使用的内存 链接的哈希映射 似乎太高了,即使考虑到 链接的哈希集 由支持 链接的哈希映射 .

    我在JProfiler中记录了对象分配,并观察了 Allocation Hot Spots 对于 链接的哈希映射 。在那里,我看到了我不理解的条目:

    • 第三个条目显示了一个名为 X.<init> 哪里 X 是我自己代码中的一个类。此方法的构造函数与无关 链接的哈希映射 。在此条目之后 Thread.run 最后显示从6.5%缓慢下降到5.8% 线程运行 。中的代码可能有什么问题 十、 ? 为什么在这里显示?
    • 大约8%的已分配内存显示在名为的热点中 java.util.HashSet.iterator 在这个条目之后,沿着百分比最高的路径(第一个条目:2.8%),我在代码中得到了几个方法,直到最后, java.lang.Thread.run 显示为(2.8%)。这意味着什么?据我所知 线程运行 方法不创建的实例 链接的哈希映射 。与 iterator 方法

    一般来说,我如何找到保留对(很多)的引用的代码 链接的哈希映射 物体?使用Heap Walker我只能看到 太多了 但是没有看到任何模式(即使在观察到GC根的路径时也是如此)。在我的实验中,所有的实例似乎都是有序的。

    可能重要的事情:

    • 我的应用程序构造了一个结果(用于进一步处理),对于这种构造,可以观察到高内存使用率。构造不断地创建对象,因此等待一个稳定的点,然后观察每一个创建的点 链接的哈希映射 对象是不可能的。
    • 我有很好的计算机可以调试(最多48个内核和192GByte的RAM,甚至更多)。
    • java版本“1.7.0_13”(java(TM)SE运行时环境(内部版本1.7.0_13-b20), Java HotSpot(TM)64位服务器虚拟机(内部版本23.7-b01,混合模式)
    • JProfiler 7.2.2(版本7157),已获得许可
    1 回复  |  直到 12 年前
        1
  •  5
  •   Ingo Kegel    12 年前

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

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

    enter image description here

    至于你关于分配热点的问题,以及为什么显示Thread.run方法:这些是 背面痕迹 ,它们显示了热点是如何被调用的,节点上的所有数字都是对顶部热点的贡献。最深的节点将一直是一个入口点,通常是Thread.run方法或main方法。

    推荐文章