1. 程式人生 > >記憶體洩露排查

記憶體洩露排查

https://blog.csdn.net/fishinhouse/article/details/80781673

  • jps -l
    • 檢視虛擬機器屬於哪個程序
  • jstat -gcutil 20954 1000
    • 每1000毫秒查詢一次,一直查。
    • gcutil的意思是已使用空間站總空間的百分比。
    • 查詢結果表明:這臺伺服器的
      • 新生代Eden區(E,表示Eden)使用了28.30%(最後)的空間,
      • 兩個Survivor區(S0、S1,表示Survivor0、Survivor1)分別是0和8.93%,
      • 老年代(O,表示Old)使用了87.33%。
        • 程式執行以來共發生Minor GC(YGC,表示Young GC)101次,總耗時1.961秒,
        • 發生Full GC(FGC,表示Full GC)7次,Full GC總耗時3.022秒,
        • 總的耗時(GCT,表示GC Time)為4.983秒。
  • jmap -histo:live 20954
    • live 是可選引數,代表存活的物件
    • 紅線部分:
      • 可以看出HashTable中的元素有5000多萬,佔用記憶體大約1.5G的樣子。這肯定不正常。
  • MAT 分析工具

    • 補充jmap線上分析

      • jmap比較籠統,明顯的問題能檢查出來
    • 修改MAT配置

      • MemoryAnalyzer.ini檔案
      • Xmx引數,該引數表示最大記憶體佔用量,預設為1024m
    • 從jmap獲取 .hprof 檔案
      • jmap -dump:format=b,file=<dumpfile.hprof> <pid>
    • 選擇Leak Suspects Report, Finish就可以進入MAT分析頁面的首頁
    • 在首頁上比較有用的是Histogram和Leak Suspects
    • 點選Leak Suspects會在堆轉儲檔案同目錄內生成一個Leak Suspects.zip檔案,
      • 同時也會從首頁跳轉到Leak Suspects頁面
    • 解壓該檔案後可以通過瀏覽器開啟分析結果
    • Leak Suspects頁面
      • 從中找你熟悉的程式碼
    • 點選Details進入詳情頁面
      • Shortest Paths To the Accumulation Point表示GC root到記憶體消耗聚集點的最短路徑
      • All Accumulated Objects by Class列舉了該物件所儲存的所有內容
      • 為了找到記憶體洩露,我獲取了兩個堆轉儲檔案,兩個檔案獲取時間間隔是一天
        • 對比兩個檔案的物件,通過對比後的結果可以很方便定位記憶體洩露。
        • MAT同時開啟兩個堆轉儲檔案,分別開啟Histogram
        • 在下圖中方框1按鈕用於對比兩個Histogram,對比後在方框2處選擇Group By package,然後對比各物件的變化
        • -64的意思是,倆檔案中該物件比對,前者比後者少了64個
        • 我記憶體洩露位置是一個list,這個list只在這裡一直不停的往裡新增eventInfo物件,卻沒有釋放過。