日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java性能分析与问题定位 实战

發布時間:2025/3/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java性能分析与问题定位 实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 常用命令
      • APM監控工具
      • eclipseMAT內存分析工具
        • 決策樹
        • 直方圖

今天我們來聊下生產環境排查、定位問題的工具和方法。

常用命令

jdk提供的工具類,可以用來獲取java進程的內存、線程、垃圾回收等信息。

  • jstack —— 獲取線程堆棧信息:

jstack -l 7055 > store-back.jstatck

  • jmap —— 獲取堆中的對象信息(類的實例等)

jmap -dump:format=b,file=store-back.hprof 12131說明:需要使用eclipse MAT或者jhat工具配合,解析dump下來的內存文件。

  • OOM時自動dump方式,在java啟動腳本上添加jvm命令:
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目錄}

  • jstat —— jvm的統計信息,包含內存使用情況、垃圾回收時間、類加載等信息:
    jstat -gcutil 21891 250 7說明:21891 進程號; 250ms 采樣間隔時間,單位毫秒; 7 采集次數

APM監控工具

通常,排查生產環境的問題,我們不會遠程連到服務器,使用jstack、jmap命令獲取相關信息,因為這樣效率太低,而且生產環境有諸多限制。我比較習慣使用APM(Application Performance Monitor)工具來快速定位和排查問題,比如pinpoint就是一款非常優秀的APM工具。

在pinpoint首頁,我們可以看到應用程序之間的拓撲圖,調用次數(一般生產環境采樣率為10%),如下圖。

圖片右上角部分(如下圖),有很多綠色的小點點,每個點代表一次http請求,橫坐標為請求時間,縱坐標為該次請求的耗時(毫秒);紅色的點表示該次請求拋異常。

我們可以用鼠標框住耗時最長的一部分“小點”,就可以查看每個請求的調用鏈(如下圖),調用鏈精確到某個應用的某個類的某個方法,并打印出執行的SQL語句;以及每個方法的執行耗時和百分比。

點擊“inspector”按鈕,可以看到每個應用(jvm進程)的內存分配情況,比如堆、永久區(java8為metaspace)占用空間,GC執行耗時,CPU消耗,每秒事務數(TPS),活躍線程數,請求響應時間,堆外直接內存空間等等數據。一目了然,猶如上帝視角。

eclipseMAT內存分析工具

還記得第一步“常用工具”中的兩個命令吧:
jmap -dump:format=b,file=store-back.hprof 12131
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目錄}

eclipseMAT就是用來分析dump下來的內存文件的。

用MAT生成內存泄漏分析報告,如下圖:

通過直方圖(Histogram)和支配樹(Dorminator Tree)分析內存泄漏:

決策樹

首先,我們通過決策樹(Dorminator Tree)來分析,按package分組:

找到占用內存最大的類,如下圖。

淺堆(shallow heap) : 指某一個對象本身所占內存大小(也包括外部對象的"引用",每個外部對象的"引用"為4或8個字節,分析時一般都是忽略這部分)。

保留堆(retained heap): 指對象本身和引用的“外部對象”的內存大小,但不包括“共享對象”(共享對象的概念后面會講到)。

深堆(deep heap): 指對象本身和引用的“外部對象”的內存大小。

MAT只顯示淺堆和保留堆的大小,很明顯,淺堆和保留堆所占空間差距過大,就非常有可能是“內存泄漏”了。

在這里,我們懷疑Activity對象可能泄漏內存,于是查下引用此對象的是誰(with incoming references)。

我們大概看一眼,就會發現,主要是WebAppClassLoader持有大量Activity對象的引用。

使用合并最短根路徑(GC ROOTS)方式,檢查對象的引用路徑,如下圖。

Merge Shortest Path To GC Roots:快速分析的一個常用功能,它能夠從當前內存映像中找到一條指定對象所在的到GC Root的最短路徑。

需要排除弱引用、軟引用及影子引用等,一般來說這三種類型的引用都不會是造成內存泄漏的原因,因為JVM遲早是會回收只存在這三種引用的資源的。

再次確認,要是WebAppClassLoader持有大量Activity對象的引用。我們通過決策樹的方式分析,大概可以判斷Activity對象是內存泄漏的最大嫌疑人。

直方圖

下面我們再通過直方圖的方式分析。

直方圖首頁,依然通過淺堆和保留堆來分析,發現FindShoppingCartByType對象可能導致內存泄漏。

查看引用人是誰(with incoming references)

咦,又看到熟悉的人了,Activity……

依然使用合并最短根路徑(GC ROOTS)方式,檢查對象的引用路徑,如下圖。

根據下圖,得出結論:主要是WebAppClassLoader持有大量Activity對象的引用;Activity對象持有大量FindShoppingCartByType對象的引用。

因為本例的程序是部署在tomcat中,這就相當于是Activity對象常駐內存,無法在GC時釋放。通過閱讀代碼,發現Activity對象是使用static聲明的變量,符合我們的推斷。至此,內存泄漏問題定位到了原因,后面就是改代碼啦。

總結

以上是生活随笔為你收集整理的java性能分析与问题定位 实战的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。