如何定位常見Java性能問題


性能優化一向是後端服務優化的重點,但是線上性能故障問題不是經常出現,或者受限於業務產品,根本就沒辦法出現性能問題,包括筆者自己遇到的性能問題也不多,所以爲了提前儲備知識,當出現問題的時候不會手忙腳亂,我們本篇文章來模擬下常見的幾個Java性能故障,來學習怎麼去分析和定位。

Linux性能監測命令

top

top命令使我們最常用的Linux命令之一,它可以實時的顯示當前正在執行的進程的CPU使用率,內存使用率等系統信息。
在這裏插入圖片描述
Cpu(s):
6.4%us 用戶空間佔用CPU百分比
6.5%sy 內核空間佔用CPU百分比
0.0%ni 用戶進程空間內改變過優先級的進程佔用CPU百分比
87.1%id 空閒CPU百分比

top -Hp <pid>可以查看某一個線程的系統資源使用情況。
在這裏插入圖片描述

vmstat

vmstat是一個指定週期和採集次數的虛擬內存檢測工具,可以統計內存,CPU,swap的使用情況,它還有一個重要的常用功能,用來觀察進程的上下文切換

比如vmstat 5 5命令,指的是每隔5秒做一次採樣,總共做5次採樣。
在這裏插入圖片描述
r: 運行隊列中進程數量(當數量大於CPU核數表示有阻塞的線程)
b: 等待IO的進程數量
swpd: 使用虛擬內存大小
free: 空閒物理內存大小
buff: 用作緩衝的內存大小(內存和硬盤的緩衝區)
cache: 用作緩存的內存大小(CPU和內存之間的緩衝區)
si: 每秒從交換區寫到內存的大小,由磁盤調入內存
so: 每秒寫入交換區的內存大小,由內存調入磁盤
bi: 每秒讀取的塊數
bo: 每秒寫入的塊數
in: 每秒中斷數,包括時鐘中斷。
cs: 每秒上下文切換數。
us: 用戶進程執行時間百分比(user time)
sy: 內核系統進程執行時間百分比(system time)
wa: IO等待時間百分比
id: 空閒時間百分比

pidstat

pidstat 是 Sysstat 中的一個組件,也是一款功能強大的性能監測工具,top 和 vmstat 兩個命令都是監測進程的內存、CPU 以及 I/O 使用情況,而 pidstat 命令可以檢測到線程級別的。

在這裏插入圖片描述

UID :被監控任務的真實用戶ID。
TGID :線程組ID。
TID:線程ID。
cswch/s:主動切換上下文次數,這裏是因爲資源阻塞而切換線程,比如鎖等待等情況。
nvcswch/s:被動切換上下文次數,這裏指CPU調度切換了線程。

JDK 監控和故障處理工具

這些命令在 JDK 安裝目錄下的 bin 目錄下:

  • jps (JVM Process Status): 類似 UNIX 的 ps 命令。用戶查看所有 Java 進程的啓動類、傳入參數和 Java 虛擬機參數等信息;
  • jstat( JVM Statistics Monitoring Tool): 用於收集 HotSpot 虛擬機各方面的運行數據;
  • jinfo (Configuration Info for Java) : Configuration Info forJava,顯示虛擬機配置信息;
  • jmap (Memory Map for Java) :生成堆轉儲快照;
  • jhat (JVM Heap Dump Browser ) : 用於分析 heapdump 文件,它會建立一個 HTTP/HTML 服務器,讓用戶可以在瀏覽器上查看分析結果;
  • jstack (Stack Trace for Java):生成虛擬機當前時刻的線程快照,線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合。

jps:查看所有 Java 進程

jps:顯示虛擬機執行主類名稱以及這些進程的本地虛擬機唯一 ID(Local Virtual Machine Identifier,LVMID)。
在這裏插入圖片描述
jps -q :只輸出進程的本地虛擬機唯一 ID。
在這裏插入圖片描述
jps -l:輸出主類的全名,如果進程執行的是 Jar 包,輸出 Jar 路徑。
在這裏插入圖片描述
jps -m:輸出傳遞給 Java 進程 main() 函數的參數。
在這裏插入圖片描述

jstat: 監視虛擬機各種運行狀態信息

jstat(JVM Statistics Monitoring Tool) 使用於監視虛擬機各種運行狀態信息的命令行工具。 它可以顯示本地或者遠程(需要遠程主機提供 RMI 支持)虛擬機進程中的類信息、內存、垃圾收集、JIT 編譯等運行數據,在沒有 GUI,只提供了純文本控制檯環境的服務器上,它將是運行期間定位虛擬機性能問題的首選工具。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 21387 1000 10表示分析進程 id 爲 31736 的 gc 情況,每隔 1000ms 打印一次記錄,打印 10 次停止,每 3 行後打印指標頭部。
在這裏插入圖片描述
S0C:第一個倖存區的大小
S1C:第二個倖存區的大小
S0U:第一個倖存區的使用大小
S1U:第二個倖存區的使用大小
EC:伊甸園區的大小
EU:伊甸園區的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法區大小
MU:方法區使用大小
CCSC:壓縮類空間大小
CCSU:壓縮類空間使用大小
YGC:年輕代垃圾回收次數
YGCT:年輕代垃圾回收消耗時間
FGC:老年代垃圾回收次數
FGCT:老年代垃圾回收消耗時間
GCT:垃圾回收消耗總時間

又比如,jstat -class 21387 1000 3統計類加載的信息。
在這裏插入圖片描述
Loaded:加載class的數量
Bytes:所佔用空間大小
Unloaded:未加載數量
Bytes:未加載佔用空間
Time:時間

又比如,jstat -compiler 21387 1000 3統計編譯的信息。
在這裏插入圖片描述
Compiled:編譯數量。
Failed:失敗數量
Invalid:不可用數量
Time:時間
FailedType:失敗類型
FailedMethod:失敗的方法

jinfo: 實時地查看和調整虛擬機各項參數

jinfo vmid :輸出當前 jvm 進程的全部參數和系統屬性 (第一部分是系統的屬性,第二部分是 JVM 的參數)。

jinfo -flag name vmid :輸出對應名稱的參數的具體值。比如輸出 MaxHeapSize、查看當前 jvm 進程是否開啓打印 GC 日誌 ( -XX:PrintGCDetails :詳細 GC 日誌模式,這兩個都是默認關閉的)。

jmap:生成堆轉儲快照

jmap(Memory Map for Java)命令用於生成堆轉儲快照。 如果不使用 jmap 命令,要想獲取 Java 堆轉儲,可以使用 “-XX:+HeapDumpOnOutOfMemoryError” 參數,可以讓虛擬機在 OOM 異常出現之後自動生成 dump 文件,Linux 命令下可以通過 kill -3 發送進程退出信號也能拿到 dump 文件。

jmap 的作用並不僅僅是爲了獲取 dump 文件,它還可以查詢 finalizer 執行隊列、Java 堆和永久代的詳細信息,如空間使用率、當前使用的是哪種收集器等。和jinfo一樣,jmap有不少功能在 Windows 平臺下也是受限制的。

jhat: 分析 heapdump 文件

jhat 用於分析 heapdump 文件,它會建立一個 HTTP/HTML 服務器,讓用戶可以在瀏覽器上查看分析結果。

jstack :生成虛擬機當前時刻的線程快照

jstack(Stack Trace for Java)命令用於生成虛擬機當前時刻的線程快照。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合.

生成線程快照的目的主要是定位線程長時間出現停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等都是導致線程長時間停頓的原因。線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做些什麼事情,或者在等待些什麼資源。

JDK 可視化分析工具

JConsole:Java 監視與管理控制檯

JConsole 是基於 JMX 的可視化監視、管理工具。可以很方便的監視本地及遠程服務器的 java 進程的內存使用情況。你可以在控制檯輸出console命令啓動或者在 JDK 目錄下的 bin 目錄找到jconsole.exe然後雙擊啓動。

Visual VM:多合一故障處理工具

VisualVM 提供在 Java 虛擬機 (Java Virutal Machine, JVM) 上運行的 Java 應用程序的詳細信息。在 VisualVM 的圖形用戶界面中,您可以方便、快捷地查看多個 Java 應用程序的相關信息。Visual VM 官網:https://visualvm.github.io/ 。Visual VM 中文文檔:https://visualvm.github.io/documentation.html。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章