最近在做項目的時候遇到一個內存泄漏,最后通過MAT定位了問題, 先介紹一下MAT的一些基本概念:
Shallow Heap:對象本身占用內存的大小,不包含對其他對象的引用,也就是對象頭加成員變量(不是成員變量的值)的總和
Retained Heap:是該對象自己的shallow size,加上從該對象能直接或間接訪問到對象的shallow size之和。換句話說,retained size是該對象被GC之后所能回收到內存的總和。
直接上圖..
1. 生成用於內存分析的dump文件
(1)在tomcat的啟動腳本里直接配置jconsole的監控用端口:
-Dcom.sun.management.jmxremote.port=10010 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.1.1.1
(2) 使用jvisualvm連接tomcat實例,並導出dump文件
(3) 下載到本地並用MAT打開,直接默認並點擊finish
(4) MAT自動分析得出一個可能的內存泄漏的地方,通過此處我們已經基本可以知道是那個類的問題了...
(5)點擊details,查看詳細:
此處會有4部分:
Shortest Paths To the Accumulation Point
GC root到聚集點的最短路徑,就是持有可能泄漏內存對象的最近一層
Accumulated Objects in Dominator Tree
對象聚集詳情,這個地方我們經常用來看完整的reference chain
Accumulated Objects by Class in Dominator Tree
這里能找到被聚集的對象實例的類名,可以看到某個類被實例化多少次
All Accumulated Objects by Class
這個好像比第三個更細 具體到類的屬性了
查看Accumulated Objects in Dominator Tree詳情,可以看到java.util.concurrent.LinkedBlockingQueue類的對象占用了MAT檢測到的可能泄漏的內存
點擊這個Class,查看持有這些Object的Class:
因此我們可以知道是這兩個類持有了 java.util.concurrent.LinkedBlockingQueue對象,注意:下圖從上往下是層層引用關系
至此內存泄漏問題定位結束.
參考:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html