java Young GC排查


最近線上某站點young gc有點頻繁,經過排查確定了問題,這里記錄一下
遇到GC,三步走 
1. 確認是哪些對象引起的GC 
2. 找到這些對象是哪里構造的
3. 根據情況進行優化。 

一般情況下,我們可以通過jmap dump的方式把堆dump出來進行分析,但dump出來的是一個靜態文件。反應的是某一時刻的情況, young gc 中的對象存活時間較短,dump出的文件不一定能反應出問題,所以這里我使用了jmap histo(注意:這里的jmap histor只是顯示對象的個數和大小,如果要知道對象屬性的值,還是要dump)

jmap -histo pid  #如果使用jmap -histo:live pid 則會觸發一次full gc

這個命令會顯示Java堆中的對象的個數和總大小,並且按照大小排列。 這里我們並不需要這么多。 

jmap -histo pid| sed -n '3,23p' 

這里只取了前20條, 這個命令只能反應某一時刻的情況,如果想要持續觀察

watch -n 5 -d   'jmap -histo pid | sed -n '3,23p''

上面的命令 每5S刷新一次,可以看到有變化的對象

watch -n 5 -d 'jmap -histo pid | sed -n '3,23p' >> obj.log'

上面的命令是將數據記錄到文件,我們可以讓命令持續2分鍾(盡量保證能經歷2次GC),然后從服務器上拿到這個文件,寫一個python腳本進行解析,解析出來后,導出到excel ,並用透視圖繪制成折線圖。

這里基本就可以看出來會被GC的對象。 

找出了被GC的對象,接下里就是找出這些對象在哪里構造的,如果這個對象只有一個地方被構造,則可以直接定位到,如果在多個地方被構造,則需要找出被構造最多次的地方。 這里直接借助阿里的Arthas。

stack xx.xx <init>  #<init> 表示構造函數

這里就是找出哪里在調用該類的構造函數,並且打印出堆棧,結果可能會很多,導出來,根據堆棧信息,找出top1, 可以導出多次,最后匯總。 

這里根據堆棧信息找到了代碼,根據代碼,分析了上下文,發現有些對象可以復用, 這里采用了享元模式, 把其中一些對象改為支持單例模式,至此結束。
當然根據實際情況, 優化的方式不限於代碼,也可以調整一些JVM參數,比如新生代的內存大小等。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM