我的应用程序需要大约10 GB的RAM用于特定输入,其中常规输入大约1 GByte就足够了。使用JProfiler进行更密切的分析表明(在GC之后)java.util.*
的标准类使用了相当多的内存:
LinkedHashMap$Entry
,HashMap$Entry[]
,LinkedHashMap
,HashMap$KeySet
,HashMap$EntrySet
,LinkedHashSet
,TreeMap$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
中可能出现什么问题?为什么会在这里显示?X
的热点中。沿着具有最高百分比(第一个条目:2.8%)的路径进入此条目之后,我在代码中获得了几个方法,直到最后显示java.util.HashSet.iterator
(具有2.8%)。这是什么意思?据我所知,java.lang.Thread.run
方法不会创建Thread.run
的实例。与LinkedHashMap
方法的连接是什么?一般来说,如何找到引用(很多)iterator
个对象的代码?使用Heap Walker我只能看到那些实例的 lot ,但看不到任何模式(即使在观察GC根路径时)。在我的实验中,所有实例似乎都是有序的。
可能很重要的事情:
LinkedHashMap
对象是不可能的。答案 0 :(得分:5)
一般来说,如何找到引用(很多)LinkedHashMap对象的代码?
在堆沃克中,选择&#34; LinkedHashMap&#34;并创建一个新的对象集。然后切换到&#34;参考&#34;查看并显示&#34;累计传入参考&#34; 。在那里,您可以分析整个对象集的引用。
关于分配热点以及为什么显示Thread.run方法的问题:这些是后退跟踪,它们显示了如何调用热点以及节点上的所有数字都是对顶部热点的贡献。最深的节点将始终是一个入口点,通常是Thread.run方法或主方法。