1、發現問題1)、使用w命令查看CPU的Load情況,Load越高說明問題越嚴重;2)、使用jstat查看FGC發生的頻率及FGC所花費的時間,FGC發生的頻率越快、花費的時間越高,問題越嚴重;
2、匯出資料:在應用快要發生FGC的時候把堆匯出來1)、查看快要發生FGC使用命令:jmap -heap <pid>會看到如結果: 以上包括了新生代、老年代及持久代的當前使用方式,如果不停的重複上面的命令,會看到這些數位變化,變化越大說明系統存在問題的可能性越大,特別是被紅色圈起來的老年代的變化情況。現在看到的這個值為使用率為99%或才快接近的時候,就立即可以執行匯出堆棧的操作了。 註:這是因為我這裡沒有在jvm參數中使用"-server"參數,也沒有指定FGC的閥值,線上上的應用中通過會指定CMSInitiatingOccupancyFraction這個參數來指定當老年代使用了百分之多少的時候,通過CMS進行FGC,當然這個參數需要和這些參數一起使用“-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection
-XX:+UseCMSInitiatingOccupancyOnly”,CMSInitiatingOccupancyFraction的預設值是68,現在中文站線上的應用都是70,也就是說當老年代使用率真達到或者超過70%時,就會進行FGC。 2)、將資料匯出:jmap -dump:format=b,file=heap.bin <pid>這個時候會在目前的目錄以產生一個heap.bin這個二進位檔案。
3、通過命令查看大對象也是使用jmap的命令,只不過參數使用-histo使用:jmap -histo <pid>|less可得到如下包含對象序號、某個對象樣本數、當前對象所佔記憶體的大小、當前對象的全限定名,如:
查看對象數最多的對象,並按降序排序輸出:
執行:jmap -histo <pid>|grep alibaba|sort -k 2 -g -r|less結果查看佔用記憶體最多的最象,並按降序排序輸出:執行:jmap -histo <pid>|grep alibaba|sort -k 3 -g -r|less結果
4、資料分析這個時候將dump出的檔案在ECLIPSE中開啟,使用MAT進行分析(ECLIPSE需要先安裝MAT外掛程式),會展示如下:
可以從這個圖看出這個類java.lang.ref.Finalizer佔用500多M,表示這其中很多不能夠被回對象的對象,此時點開hisgogram視圖,並通過Retained
Heap進行排序,如下:
可以看出,被線線框圈起來的三個對象佔用量非常大,那說明這幾個大的對象並沒有被釋放,那現在就可以有針對性的從代碼中去找這幾個對象為什麼沒有被釋放了。再切換到dominator_tree視圖:
這裡可以看到velocity渲染也存在著問題,以及資料庫的請求也比較多。
5、最佳化最佳化的思路就是上面所列出來的問題,查看實現代碼中所存在問題,具體問題具體分析。
本文出自:馮立彬的部落格