JProfiler的記憶體視圖會話提供了記憶體使用量情況的動態更新視圖以及分配點的資訊視圖。所有的視圖都有幾個聚集層並且能夠顯示現有存在的對象和作為記憶體回收的對象。本文主要介紹如何意識到記憶體流失以及尋找記憶體流失的幾種方法。
意識到記憶體流失
懷疑記憶體流失的第一步就是查看 "Memory"和"Recorded objects" 遙感勘測視圖。當應用程式出現記憶體流失時,視圖中會顯示出帶有震蕩的線性積極趨勢。如果沒有這樣的線性趨勢,您的應用程式可能只是消耗了大量的記憶體,而不是記憶體流失。處理方法很簡單,找出佔用大量記憶體的類或陣列,盡量減少類或陣列的數量。
使用差異縮小記憶體流失
尋找記憶體流失的起源的第一步就是尋找物件檢視和所記錄的物件檢視的差異。簡單的記憶體流失可以利用差分功能來追查。
觀察物件檢視和所記錄的物件檢視的差異,然後找出該差異是有哪些類引起的。然後,當切換到熱點視圖時,選擇問題類別,然後觀察問題執行個體所分配到的差異列。此時,知道執行個體建立的方法。
堆遍曆器和記憶體流失
當擷取了一堆快照時,首先你必須建立一個帶有對象執行個體的對象集。如果你在動態記憶體視圖中已經收窄記憶體流失原因的範圍,你可以使用 "show selection in heap walker"來儲存操作並啟動堆遍曆器。
利用物件檢視找出記憶體流失原因
大多數的記憶體流失可以被追溯到對象叢集。這將產生一些大的retained size的對象。最大的物件檢視列出了帶有最大retained size的對象。你可以利用該樹形向下切入從而發現錯誤引用。
使用參考圖找到記憶體流失的原因
找出記憶體流失的核心工具是堆遍曆器中的參考圖。依次開啟傳入引用,你可能會立即發現一個錯誤引用。在複雜的系統中,這往往是不可能的。在這種情況下,你必須要找到一個或多個"garbage collector roots"。Garbage collector roots是JVM中的點,不受記憶體回收機制的約束。當你選擇了傳入引用或圖形中的一個對象時,頂部的[Show path to GC root] 按鈕被啟用。
garbage collector roots非常多,若全部顯示它們,可能會造成大量堆積,。此外,尋找garbage collector roots也很耗時。 如果找到成千上萬的roots,計算的時間很長而且會佔用大量記憶體。為了防止這些問題,最好開始時從單個garbage collector root 開始尋找,然後根據利用 UP to roots 根據需要慢慢增加garbage collector root。
garbage collector root 的鏈條可以很長,:
使用cumulated references views以尋找記憶體流失的原因
在某些情況下,您可能無法成功地縮小對象設定的規模。你的對象集中可能仍包含了大量的執行個體或者在此情況下,使用參考圖不可能會提供任何見解。這時,堆遍曆器的引用視圖中的 the cumulated reference tables 就可排上用場了。cumulated incoming reference table顯示了當前對象集中所有可能的參考型別:
從參考型別中,你就可以縮小對象集。例如,您可能知道那些參考型別是正常的,那些是不正常的。