Java 應用性能問題最終都會映射到操作系統資源:CPU、內存、磁盤、網絡。掌握 OS 級監控工具,能在 JVM 工具介入前快速定位瓶頸域。本文系統介紹 Linux/Windows 核心監控命令、關鍵指標解讀、Java 應用視角的分析方法論。
# vmstat 5 (每 5 秒采樣,持續運行)
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 236456 2259632 200052 730348 0 0 1 6 1 1 37 8 55 0 0
2 0 236456 2259624 200052 730348 0 0 0 10 179 332 40 7 53 0 0
# 關鍵列解讀
r: 運行隊列長度 (可運行線程數) → 持續 > CPU核心數 表示 CPU 瓶頸
us: 用戶態 CPU% (應用代碼) → 高表示業務邏輯計算密集
sy: 系統態 CPU% (內核/系統調用) → 高表示頻繁上下文切換、IO、鎖競爭
id: 空閒% → 低表示 CPU 飽和
wa: IO 等待% → 高表示磁盤/網絡 IO 瓶頸
st: 虛擬機偷取% (雲環境) → 高表示宿主機超售
查看每個 CPU 核心的使用率,發現單核熱點 (如單線程計算、GC 線程佔滿一核)。
查看特定 Java 進程的用戶/系統 CPU 佔用,排除其他進程干擾。
# free -h (人類可讀)
total used free shared buff/cache available
Mem: 31G 8.2G 1.5G 500M 21G 22G
Swap: 0B 0B 0B
# 關鍵概念
used = total - free - buff/cache
available = free + 可回收的 buff/cache (真正可用於新進程)
Java 堆外內存 = RSS - Xmx - Metaspace - ThreadStack - CodeCache - DirectMemory
# iostat -xmt 5 (擴展統計、兆字節、時間戳)
Device r/s w/s rMB/s wMB/s await svctm %util
sda 0.00 34.60 0.00 0.23 5.04 0.04 2.02
# 關鍵指標
r/s, w/s: 每秒讀/寫次數
rMB/s, wMB/s: 吞吐量
await: 平均等待時間 (ms) = 隊列等待 + 服務時間
svctm: 平均服務時間 (ms)
%util: 設備利用率 → 接近 100% 表示磁盤飽和
# Java 應用視角
pidstat -p -d 5
# kB_rd/s, kB_wr/s, kB_ccwr/s (取消寫入)
# 高 IO 通常源於:日志狂寫、堆外內存交換、GC 時的堆轉儲、數據庫同步
# ss -antp | grep java (查看 Java 進程連接)
# nethogs -p (按進程顯示實時帶寬)
# iftop -i eth0 (接口級流量)
# 關鍵指標
Tx/Rx bytes: 發送/接收字節數
Retrans: 重傳數 → 高表示網絡擁塞/丟包
ESTAB/TIME_WAIT: 連接狀態分布 → 大量 TIME_WAIT 表示短連接風暴
top -H -p :查看 Java 進程所有線程 CPU 佔用,定位熱點線程 (配合 jstack 轉換 nid 為 16 進制)glances:單屏聚合 CPU/內存/磁盤/網絡/進程/容器,適合快速巡檢perfmon.msc# 實時查看 Java 進程 CPU
typeperf "\Process(java)\% Processor Time" -si 5
# 創建數據收集器 (性能日志)
logman create counter JavaPerf -c "\Process(java)\% Processor Time" "\Memory\Available MBytes" -si 10 -o C:\perf\java.blg -f bin
logman start JavaPerf
# ... 壓測 ...
logman stop JavaPerf
# 用 relog 轉 CSV 或 PerfMon 打開分析
| 現象 | OS 指標 | Java 層排查 |
|---|---|---|
| 用戶態高 (us%) | vmstat us 高、pidstat 進程 us 高 | 業務邏輯計算密集、正則匹配、序列化、GC 併發標記線程 |
| 系統態高 (sy%) | vmstat sy 高、上下文切換 cs 高 | 鎖競爭 (synchronized/Lock)、頻繁系統調用 (IO、反射、JNI)、線程過多 |
| IO 等待高 (wa%) | vmstat wa 高、iostat await/%util 高 | 日志異步化、堆外內存、數據庫慢查詢、GC 時堆轉儲 |
| 運行隊列長 (r) | vmstat r > CPU核心數 | 線程池過大、鎖爭搶、CPU 密集任務並發度過高 |
vmstat si/so > 0 → 物理內存不足,OS 將匿名頁換出。Java 堆被 swap 會導致 GC 停頓劇增 (ms→s)free available < 10% 總內存 → 風險區pidstat -r 或 top RES → 疑似堆外/直接內存/元空間/線程棧洩漏iostat -xmt 5 確認 %util、await 異常pidstat -d -p 確認是 Java 進程導致FileChannel.force() 頻繁調用、數據庫同步提交、堆轉儲文件寫入操作系統監控是性能分析的地基。熟練掌握 vmstat/iostat/pidstat/ss/top -H (Linux) 以及 PerfMon/typeperf/resmon (Windows),能在幾分鐘內判斷瓶頸是計算、IO、鎖、內存還是網絡,為後續 JVM 級工具 (jstack/jmap/Arthas/JFR) 指明方向。
下篇預告:Java 內置監控工具全景—— jcmd、jstat、jmap、jstack、jhat、JConsole、VisualVM、JFR、Async Profiler、Arthas 實戰指南。