2013-02-19 109 views
3

我的應用程序需要大約10 GB的特定輸入RAM,其中對於常規輸入大約1 GByte就足夠了。與JProfiler的進一步分析顯示,(後GC)相當多的內存是從java.util.*使用標準類:JProfiler:試圖找到內存泄漏

LinkedHashMap$EntryHashMap$Entry[]LinkedHashMapHashMap$KeySetHashMap$EntrySetLinkedHashSetTreeMap$Entry,並TreeMap(按照這個順序),和相關的類。以下條目屬於我自己的代碼中的一個類,其中實例的數量和使用的內存量似乎非常合理。

在具有大約900兆字節我看到在All Objects視圖以下Size條目的總堆的使用情況的細節:

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

LinkedHashMap使用的內存似乎太高,即使考慮到每個LinkedHashSet都由LinkedHashMap支持。

我在JProfiler中記錄了對象分配,並觀察Allocation Hot SpotsLinkedHashMap。在那裏,我看到,我不明白的條目:

  • 第三個條目顯示了熱點(與分配內存的6.5%)命名X.<init>其中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對象的代碼?使用堆行程我只能看到這些實例的批次,但沒有看到任何模式(即使觀察到GC根的路徑)。在我的實驗中,所有實例似乎都是按順序排列的。

可能重要的事情:

  • 我的申請構建的結果(以供進一步處理),並且對於該結構,高內存使用情況是觀察。施工不斷創建物體,因此等待穩定點,然後觀察每個創建的物體是不可能的。
  • 我有很好的電腦可以調試(最多48個內核和192 GB的RAM,甚至更多)。
  • Java版本 「1.7.0_13」(Java(註冊商標)SE運行時環境(建立1.7.0_13-B20), 爪哇熱點(TM)64位服務器VM(構建23.7-B01,混合模式))
  • JProfiler的7.2.2(7157建立),行貨

回答

5

在一般情況下,我怎麼發現不斷引用(很多)LinkedHashMap的對象的代碼?

在堆步行者中,選擇「LinkedHashMap」並創建一個新的對象集。然後切換到「參考」視圖並顯示「累積傳入參考」。在那裏,您可以分析整個對象集的引用。

enter image description here

至於你提到的分配熱點問題,爲什麼顯示的Thread.run方法:這是背部走線,他們呈現怎樣的熱點已被調用,並在節點上的所有號碼是對頂部熱點的貢獻。最深的節點將始終是一個入口點,通常是Thread.run方法或主要方法。

+0

這肯定有幫助,我不知何故忽略了累積的意見......感謝提示!關於回溯:這是否意味着創建實例的5.8%和2.8%(基於我的數字)是由調用'Thread.run'方法的代碼創建的?或者換句話說,我是否必須尋找沿着回溯軌跡改變百分比的方法(比如從1%跳到4%)? – 2013-02-19 11:59:11

+1

不,它的所有內容都是在熱點中創建的,在後面的跟蹤節點中沒有任何內容。熱點可以用不同的調用堆棧調用,後面的跟蹤解決這個信息,即後面的跟蹤節點上的數字只顯示沿着該特定調用堆棧提供的部分。 – 2013-02-19 12:45:46

+0

謝謝,我現在明白了。 – 2013-02-19 14:22:02