最近解決了一次線上內(nèi)存泄漏的BUG别凹,將解決問題的過程記錄如下:
1.登錄服務(wù)器查詢JAVA進(jìn)程heap的概要信息,使用命令:jmap –heap 3772洽糟,結(jié)果如下圖所示:
從上圖可見炉菲,老年代已使用99%,這時JVM會不停的GC坤溃,GC時會Stop-the-world拍霜,當(dāng)Stop-the-world發(fā)生時,除了GC所需的線程以外薪介,所有線程都處于等待狀態(tài)祠饺,直到GC任務(wù)完成。如果老年代已使用99%汁政,這時基本大部分時間都在GC道偷,所以應(yīng)用也就無法正常提供服務(wù)。
2.查詢JAVA進(jìn)程每個class的實(shí)例數(shù)目记劈,使用命令:jmap –histo:live 3772勺鸦,結(jié)果如下圖如示:
通過上述命令基本可以定位到實(shí)例數(shù)目異常的class,定位到異常的class后目木,有的時候祝旷,僅僅通過review源代碼,就可以定位到問題所在,但這種情況很少發(fā)生怀跛,大部分情況都是定位不到問題所在,這時就要查找這些實(shí)例的Paths from GC Roots柄冲,這樣才能定位到這些實(shí)例被哪些對象所持有吻谋,從而導(dǎo)致的內(nèi)存泄漏。
我使用的Java profiler工具是yourkit java profiler现横,操作過程如下漓拾,安裝及配置yourkit
java profiler的過程暫時不表,這里我只說通過工具如何查找對象的Paths from GC
Roots戒祠。
3.點(diǎn)擊yourkit java profiler工具欄上Capture Memory Snapshot按鈕骇两,會生成JAVA進(jìn)程heap的一個快照。
4.選擇創(chuàng)建的快照姜盈,并點(diǎn)擊上面的Memory頁簽以及ObjectExplorer頁簽低千,右鍵點(diǎn)擊下面的實(shí)例,就可以查看Paths from GC Roots馏颂。
5.查看對象Paths from GC Roots的界面如下圖所示示血,即可準(zhǔn)確定位到內(nèi)存泄漏的點(diǎn)。
以上僅僅是一個粗略的記錄救拉,解決問題的過程其實(shí)是花費(fèi)了整整一天的時間才定位到內(nèi)存泄漏的點(diǎn)难审,因?yàn)槭堑谝淮危芏鄦栴}要自己摸索亿絮,所以比較慢告喊,如果再遇到類似問題,問題的過程應(yīng)該會快很多派昧,所以對本次過程也做一個粗略的記錄黔姜,希望可以給其它同學(xué)以啟發(fā)。
如果有想了解細(xì)節(jié)的同學(xué)斗锭,歡迎留言或私信溝通地淀。