Linux進程資源占用詳解
Linux進程資源占用分析指南
本文檔介紹在 Linux 系統(tǒng)下如何分析和監(jiān)控進程的資源占用情況,包括 CPU、內(nèi)存、I/O 等關(guān)鍵指標的查看方法。
快速開始
前提條件
已知進程 ID (PID)
獲取 PID 的方法:
# 通過進程名查找 pgrep process_name ps aux | grep process_name # 通過端口查找 lsof -i :port netstat -tlnp | grep :port
命令行工具
1.top命令(實時監(jiān)控)
基本用法:
top -p PID
交互式操作:
1- 顯示每個 CPU 核心的使用情況c- 切換顯示完整命令行M- 按內(nèi)存使用排序P- 按 CPU 使用排序f- 添加或刪除顯示的字段q- 退出
輸出說明:
%CPU- CPU 使用百分比%MEM- 內(nèi)存使用百分比VIRT- 虛擬內(nèi)存大小RES- 物理內(nèi)存使用(RSS)SHR- 共享內(nèi)存
2.htop(增強版 top,推薦)
基本用法:
htop -p PID
功能特點:
- 更直觀的彩色界面
- 樹狀視圖顯示進程關(guān)系(按
F5) - 可直接查看進程打開的文件(按
F2添加列) - 支持鼠標操作
- 實時顯示 CPU 和內(nèi)存使用率
快捷鍵:
F2- 設置F5- 樹狀視圖F6- 排序選擇F9- 發(fā)送信號F10- 退出
3.ps命令(快照查看)
基本資源查看:
ps -p PID -o pid,ppid,%cpu,%mem,vsz,rss,cmd
詳細資源報告:
ps -p PID -o user,pid,ppid,ni,%cpu,%mem,vsz,rss,tty,stat,start,time,cmd,etime
字段說明:
pid- 進程 IDppid- 父進程 ID%cpu- CPU 使用百分比%mem- 內(nèi)存使用百分比vsz- 虛擬內(nèi)存大?。↘B)rss- 物理內(nèi)存使用(KB)cmd- 完整命令行etime- 進程運行時間stat- 進程狀態(tài)
連續(xù)監(jiān)控:
watch -n 1 'ps -p PID -o pid,%cpu,%mem,vsz,rss,cmd'
4.pidstat(詳細資源統(tǒng)計)
安裝:
# Ubuntu/Debian sudo apt-get install sysstat # CentOS/RHEL sudo yum install sysstat
基本用法:
# 每2秒刷新一次,共顯示5次 pidstat -p PID 2 5
詳細資源監(jiān)控:
# 磁盤 I/O 統(tǒng)計 pidstat -d -p PID # 內(nèi)存頁錯誤統(tǒng)計 pidstat -r -p PID # 棧使用統(tǒng)計 pidstat -s -p PID # 線程級統(tǒng)計 pidstat -t -p PID # 綜合統(tǒng)計(CPU、內(nèi)存、I/O) pidstat -u -r -d -p PID 2 5
輸出指標:
%usr- 用戶態(tài) CPU 使用率%system- 內(nèi)核態(tài) CPU 使用率%guest- 虛擬化 CPU 使用率%CPU- 總 CPU 使用率minflt/s- 次要頁錯誤率majflt/s- 主要頁錯誤率VSZ- 虛擬內(nèi)存大小RSS- 物理內(nèi)存使用kB_rd/s- 讀取速率(KB/s)kB_wr/s- 寫入速率(KB/s)
5.atop(高級監(jiān)控)
安裝:
# Ubuntu/Debian sudo apt-get install atop # CentOS/RHEL sudo yum install atop
基本用法:
atop -p PID
功能亮點:
- 顯示磁盤負載詳情
- 網(wǎng)絡帶寬使用統(tǒng)計
- 進程級 GPU 使用(需插件支持)
- 歷史資源記錄(按
t切換時間點) - 支持記錄和回放
快捷鍵:
t- 切換時間點m- 顯示內(nèi)存信息d- 顯示磁盤信息n- 顯示網(wǎng)絡信息q- 退出
6.nmon(可視化監(jiān)控)
安裝:
# Ubuntu/Debian sudo apt-get install nmon # CentOS/RHEL sudo yum install nmon
基本用法:
nmon -p PID
交互式界面:
c- 查看 CPU 使用情況m- 查看內(nèi)存使用情況d- 查看磁盤 I/On- 查看網(wǎng)絡統(tǒng)計t- 查看進程/線程統(tǒng)計q- 退出
7.iotop(I/O 監(jiān)控)
安裝:
# Ubuntu/Debian sudo apt-get install iotop # CentOS/RHEL sudo yum install iotop
基本用法:
# 實時監(jiān)控指定進程的 I/O iotop -p PID # 顯示累計 I/O iotop -a -p PID
輸出說明:
DISK READ- 磁盤讀取速率DISK WRITE- 磁盤寫入速率SWAPIN- 交換分區(qū)使用率IO- I/O 使用百分比
8.lsof(列出打開文件)
基本用法:
# 查看進程打開的所有文件
lsof -p PID
# 查看進程打開的網(wǎng)絡連接
lsof -p PID -i
# 查看進程打開的文件描述符數(shù)量
lsof -p PID | wc -l
# 查看進程打開的具體文件類型
lsof -p PID | grep -E 'REG|DIR|CHR|FIFO|SOCK'
# 查看進程的端口占用
lsof -p PID -iTCP -sTCP:LISTEN
# 查看進程的工作目錄
lsof -p PID | grep cwd
# 查看進程打開的文件并按類型統(tǒng)計
lsof -p PID | awk '{print $5}' | sort | uniq -c
字段說明:
COMMAND- 命令名PID- 進程 IDUSER- 用戶FD- 文件描述符TYPE- 文件類型(REG=普通文件, DIR=目錄, CHR=字符設備等)DEVICE- 設備號SIZE/OFF- 文件大小或偏移量NODE- inode 號NAME- 文件路徑
9.sar(系統(tǒng)活動報告)
安裝:
# Ubuntu/Debian sudo apt-get install sysstat # CentOS/RHEL sudo yum install sysstat
基本用法:
# 查看當前 CPU 使用(每1秒刷新,共5次) sar -u 1 5 # 查看內(nèi)存使用 sar -r 1 5 # 查看 I/O 統(tǒng)計 sar -b 1 5 # 查看進程相關(guān)統(tǒng)計 sar -x PID 1 5 # 查看歷史數(shù)據(jù)(需要啟用 sysstat 數(shù)據(jù)收集) sar -u sar -r sar -b # 生成綜合報告 sar -A > sar_report.txt
優(yōu)勢:
- 可以查看歷史性能數(shù)據(jù)
- 適合長期監(jiān)控和趨勢分析
- 數(shù)據(jù)可以保存和回放
10.vmstat(虛擬內(nèi)存統(tǒng)計)
基本用法:
# 每2秒刷新一次,共顯示5次 vmstat 2 5 # 查看進程相關(guān)統(tǒng)計 vmstat -p /dev/sda1 2 5 # 顯示詳細的內(nèi)存統(tǒng)計 vmstat -s
輸出說明:
procs- 進程統(tǒng)計(r=運行隊列, b=阻塞)memory- 內(nèi)存統(tǒng)計(swpd=交換分區(qū), free=空閑內(nèi)存)swap- 交換分區(qū)使用io- I/O 統(tǒng)計(bi=塊讀取, bo=塊寫入)system- 系統(tǒng)統(tǒng)計(in=中斷, cs=上下文切換)cpu- CPU 使用百分比
11.pmap(內(nèi)存映射查看)
基本用法:
# 查看進程的內(nèi)存映射 pmap -x PID # 顯示詳細信息 pmap -XX PID # 顯示設備格式 pmap -d PID # 顯示擴展格式 pmap -X PID # 查看內(nèi)存映射摘要 pmap -q PID
輸出說明:
Address- 內(nèi)存地址范圍Kbytes- 內(nèi)存大小(KB)RSS- 實際物理內(nèi)存(KB)Dirty- 臟頁大?。↘B)Mode- 內(nèi)存權(quán)限(r=讀, w=寫, x=執(zhí)行, s=共享, p=私有)Mapping- 映射的文件或設備
用途:
- 分析內(nèi)存占用分布
- 查找內(nèi)存泄漏
- 查看共享庫占用
12.smem(內(nèi)存使用統(tǒng)計)
安裝:
# Ubuntu/Debian sudo apt-get install smem # CentOS/RHEL sudo yum install smem
基本用法:
# 查看進程內(nèi)存使用(按 PSS 排序) smem -P process_name # 查看指定 PID 的內(nèi)存使用 smem -p PID # 顯示詳細統(tǒng)計 smem -t -k -p PID # 按用戶統(tǒng)計 smem -u # 生成報告 smem -t -k -P process_name -c "pid user command pss rss"
優(yōu)勢:
- PSS (Proportional Set Size): 更準確的內(nèi)存統(tǒng)計,考慮了共享內(nèi)存
- USS (Unique Set Size): 進程獨占的內(nèi)存
- RSS (Resident Set Size): 實際物理內(nèi)存
13.ss(現(xiàn)代網(wǎng)絡連接工具)
基本用法:
# 查看進程的網(wǎng)絡連接 ss -tulpn | grep PID # 查看 TCP 連接 ss -tpn | grep PID # 查看 UDP 連接 ss -upn | grep PID # 顯示詳細信息 ss -tulnap | grep PID # 查看監(jiān)聽端口 ss -tlnp | grep PID # 統(tǒng)計連接數(shù) ss -s
相比 netstat 的優(yōu)勢:
- 更快速
- 顯示更多信息
- 更好的過濾選項
14.time命令(執(zhí)行時間統(tǒng)計)
基本用法:
# 使用 time 命令運行程序并統(tǒng)計資源 time command # 使用 /usr/bin/time 獲取更詳細信息 /usr/bin/time -v command # 查看進程運行時間 time -p sleep 5 # 詳細資源統(tǒng)計 /usr/bin/time -f "%E real, %U user, %S sys, %M KB memory" command
輸出說明:
real- 實際運行時間(墻鐘時間)user- 用戶態(tài) CPU 時間sys- 內(nèi)核態(tài) CPU 時間%M- 最大內(nèi)存使用(KB)
15.taskset/numactl(CPU 親和性和 NUMA)
基本用法:
# 查看進程的 CPU 親和性 taskset -p PID # 查看進程的 NUMA 節(jié)點 numactl --show # 查看進程的 NUMA 統(tǒng)計 numastat -p PID # 查看系統(tǒng) NUMA 信息 numactl --hardware
用途:
- 優(yōu)化進程的 CPU 綁定
- 在 NUMA 系統(tǒng)上優(yōu)化內(nèi)存訪問
- 提高緩存命中率
16.prlimit(資源限制查看)
基本用法:
# 查看進程的資源限制 prlimit --pid=PID # 查看特定資源限制 prlimit --pid=PID --as # 虛擬內(nèi)存限制 prlimit --pid=PID --rss # 物理內(nèi)存限制 prlimit --pid=PID --nofile # 文件描述符限制 prlimit --pid=PID --cpu # CPU 時間限制
常用資源限制:
AS- 虛擬內(nèi)存大小RSS- 物理內(nèi)存大小NOFILE- 文件描述符數(shù)量CPU- CPU 時間(秒)NPROC- 進程數(shù)限制
17.systemd-cgtop(systemd 進程組監(jiān)控)
基本用法:
# 查看 systemd 管理的進程組資源使用 systemd-cgtop # 查看特定服務的資源使用 systemd-cgtop /system.slice/service-name.service # 查看用戶服務的資源使用 systemd-cgtop /user.slice/user-1000.slice
適用場景:
- 監(jiān)控 systemd 管理的服務
- 查看容器資源使用(如果使用 systemd-nspawn)
- 分析服務資源消耗
18.slabtop(內(nèi)核 slab 緩存監(jiān)控)
基本用法:
# 實時查看內(nèi)核 slab 緩存使用 slabtop # 按使用量排序 slabtop -s c # 只顯示正在使用的緩存 slabtop -o
用途:
- 診斷內(nèi)核內(nèi)存泄漏
- 查看內(nèi)核緩存使用情況
- 分析系統(tǒng)內(nèi)存壓力
系統(tǒng)文件分析
/proc文件系統(tǒng)(底層信息)
/proc/PID/ 目錄提供了進程的詳細底層信息。
CPU 使用情況
# 查看進程 CPU 時間統(tǒng)計
cat /proc/PID/stat | awk '{print "用戶態(tài)CPU: " $14 " 時鐘周期"; print "內(nèi)核態(tài)CPU: " $15 " 時鐘周期"}'
# 實時監(jiān)控 CPU 使用率
while true; do
cat /proc/PID/stat | awk '{utime=$14; stime=$15; total=$14+$15; print "用戶態(tài): " utime " 內(nèi)核態(tài): " stime " 總計: " total}'
sleep 1
done
內(nèi)存使用情況
# 查看內(nèi)存詳細信息 cat /proc/PID/status | grep -E 'VmPeak|VmSize|VmRSS|VmSwap|VmHWM|VmData|VmStk|VmExe' # 字段說明: # VmPeak - 虛擬內(nèi)存峰值(KB) # VmSize - 當前虛擬內(nèi)存大?。↘B) # VmRSS - 實際物理內(nèi)存使用(KB) # VmSwap - 交換分區(qū)使用(KB) # VmHWM - 物理內(nèi)存峰值(KB) # VmData - 數(shù)據(jù)段大?。↘B) # VmStk - 棧大?。↘B) # VmExe - 可執(zhí)行文件大小(KB)
打開文件描述符
# 查看打開的文件描述符數(shù)量 ls -l /proc/PID/fd | wc -l # 查看具體打開的文件 ls -l /proc/PID/fd # 查看打開的文件列表(帶路徑) for fd in /proc/PID/fd/*; do readlink -f "$fd" done
I/O 統(tǒng)計
# 查看 I/O 統(tǒng)計信息 cat /proc/PID/io # 輸出字段說明: # rchar - 讀取字符數(shù)(包括緩存) # wchar - 寫入字符數(shù)(包括緩存) # syscr - 系統(tǒng)調(diào)用讀取次數(shù) # syscw - 系統(tǒng)調(diào)用寫入次數(shù) # read_bytes - 實際磁盤讀取字節(jié)數(shù) # write_bytes - 實際磁盤寫入字節(jié)數(shù) # cancelled_write_bytes - 取消的寫入字節(jié)數(shù)
線程信息
# 查看線程數(shù)量
ls /proc/PID/task | wc -l
# 查看每個線程的詳細信息
for tid in /proc/PID/task/*; do
echo "線程 ID: $(basename $tid)"
cat $tid/stat | awk '{print "CPU時間: " $14+$15}'
done
上下文切換
# 查看上下文切換統(tǒng)計 cat /proc/PID/status | grep -E 'voluntary_ctxt_switches|nonvoluntary_ctxt_switches' # 字段說明: # voluntary_ctxt_switches - 自愿上下文切換(等待資源) # nonvoluntary_ctxt_switches - 非自愿上下文切換(時間片到期)
網(wǎng)絡連接
# 查看進程的網(wǎng)絡連接 cat /proc/PID/net/tcp cat /proc/PID/net/udp # 或使用 netstat/lsof netstat -anp | grep PID lsof -p PID -i
資源限制
# 查看進程的資源限制 cat /proc/PID/limits # 字段說明: # Limit - 資源類型 # Soft Limit - 軟限制(可超過但會收到信號) # Hard Limit - 硬限制(不可超過) # Units - 單位
環(huán)境變量
# 查看進程的環(huán)境變量 cat /proc/PID/environ | tr '\0' '\n' # 查找特定環(huán)境變量 cat /proc/PID/environ | tr '\0' '\n' | grep VARIABLE_NAME
命令行和工作目錄
# 查看命令行參數(shù) cat /proc/PID/cmdline | tr '\0' ' ' # 查看工作目錄 readlink /proc/PID/cwd # 查看可執(zhí)行文件路徑 readlink /proc/PID/exe
內(nèi)存映射詳情
# 查看詳細的內(nèi)存映射 cat /proc/PID/maps # 查看內(nèi)存映射摘要 cat /proc/PID/smaps # smaps 提供更詳細的信息: # - 每個映射區(qū)域的詳細統(tǒng)計 # - 共享/私有內(nèi)存大小 # - 臟頁統(tǒng)計 # - 交換分區(qū)使用
進程關(guān)系
# 查看進程樹
pstree -p PID
# 查看子進程
ps --ppid PID
# 查看進程會話和進程組
cat /proc/PID/stat | awk '{print "會話ID: " $6 " 進程組: " $5}'
Cgroup 資源監(jiān)控
Cgroup v1 文件系統(tǒng)
如果進程在 cgroup 中運行(如 Docker 容器、systemd 服務),可以通過 cgroup 文件系統(tǒng)查看資源使用:
# 查找進程的 cgroup 路徑 cat /proc/PID/cgroup # 查看 CPU 使用(如果使用 CPU cgroup) cat /sys/fs/cgroup/cpu/cgroup_name/cpuacct.usage cat /sys/fs/cgroup/cpu/cgroup_name/cpu.stat # 查看內(nèi)存使用(如果使用 Memory cgroup) cat /sys/fs/cgroup/memory/cgroup_name/memory.usage_in_bytes cat /sys/fs/cgroup/memory/cgroup_name/memory.stat cat /sys/fs/cgroup/memory/cgroup_name/memory.limit_in_bytes # 查看 I/O 統(tǒng)計(如果使用 blkio cgroup) cat /sys/fs/cgroup/blkio/cgroup_name/blkio.io_service_bytes cat /sys/fs/cgroup/blkio/cgroup_name/blkio.io_serviced # 查看進程數(shù)限制 cat /sys/fs/cgroup/pids/cgroup_name/pids.current cat /sys/fs/cgroup/pids/cgroup_name/pids.max
Cgroup v2 文件系統(tǒng)
現(xiàn)代 Linux 系統(tǒng)使用 cgroup v2:
# 查找進程的 cgroup 路徑 cat /proc/PID/cgroup # 查看資源統(tǒng)計(統(tǒng)一接口) cat /sys/fs/cgroup/cgroup_name/cpu.stat cat /sys/fs/cgroup/cgroup_name/memory.current cat /sys/fs/cgroup/cgroup_name/memory.stat cat /sys/fs/cgroup/cgroup_name/io.stat # 查看資源限制 cat /sys/fs/cgroup/cgroup_name/memory.max cat /sys/fs/cgroup/cgroup_name/cpu.max
systemd 服務資源監(jiān)控
# 查看服務的資源使用 systemd-cgtop # 查看特定服務的統(tǒng)計 systemctl status service-name systemd-cgtop /system.slice/service-name.service # 查看服務資源限制配置 systemctl show service-name | grep -i limit
Docker 容器資源監(jiān)控
# 查看容器的資源使用 docker stats container_name # 查看容器的詳細資源統(tǒng)計 docker stats --no-stream container_name # 查看容器的 cgroup 信息 docker inspect container_name | grep -i cgroup # 進入容器查看 docker exec container_name cat /proc/self/cgroup
高級監(jiān)控工具
bpftrace(動態(tài)追蹤)
安裝:
# Ubuntu 20.04+ sudo apt-get install bpftrace # 或從源碼編譯
基本用法:
# 實時監(jiān)控 CPU 使用(按用戶態(tài)堆棧)
bpftrace -e 'profile:hz:99 /pid == PID/ { @[ustack] = count(); }'
# 監(jiān)控系統(tǒng)調(diào)用
bpftrace -e 'tracepoint:syscalls:sys_enter_* /pid == PID/ { @[probe] = count(); }'
# 監(jiān)控 I/O 操作
bpftrace -e 'tracepoint:block:block_rq_issue /pid == PID/ { @[comm] = count(); }'
# 監(jiān)控內(nèi)存分配
bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /pid == PID/ { @[ustack] = count(); }'
perf(性能分析)
安裝:
# Ubuntu/Debian sudo apt-get install linux-perf # CentOS/RHEL sudo yum install perf
基本用法:
# 實時查看熱點函數(shù) perf top -p PID # 記錄性能數(shù)據(jù) perf record -p PID -g sleep 10 # 查看報告 perf report # 統(tǒng)計系統(tǒng)調(diào)用 perf stat -p PID sleep 5 # 追蹤特定事件 perf trace -p PID
strace(系統(tǒng)調(diào)用追蹤)
基本用法:
# 追蹤系統(tǒng)調(diào)用并統(tǒng)計 strace -cp PID # 追蹤特定系統(tǒng)調(diào)用 strace -e trace=open,read,write -p PID # 顯示時間戳 strace -t -p PID # 統(tǒng)計系統(tǒng)調(diào)用耗時 strace -c -p PID
關(guān)鍵指標說明
指標對照表
| 指標 | 命令/文件 | 說明 | 正常范圍參考 |
|---|---|---|---|
| CPU 使用 | ps -o %cpu | 進程占用 CPU 百分比 | 0-100% |
| 內(nèi)存使用 | ps -o %mem,rss,vsz | %mem=物理內(nèi)存百分比,rss=實際物理內(nèi)存(KB),vsz=虛擬內(nèi)存大小(KB) | 根據(jù)系統(tǒng)內(nèi)存調(diào)整 |
| 線程數(shù) | ls /proc/PID/task | 任務目錄數(shù)量即為線程數(shù) | 根據(jù)應用類型 |
| I/O 讀取 | /proc/PID/io | read_bytes 顯示實際磁盤讀取 | 根據(jù)應用需求 |
| I/O 寫入 | /proc/PID/io | write_bytes 顯示實際磁盤寫入 | 根據(jù)應用需求 |
| 上下文切換 | /proc/PID/status | voluntary_ctxt_switches/nonvoluntary_ctxt_switches | 過高可能存在問題 |
| 運行時間 | ps -o etime | 進程已運行時間 (格式: [[DD-]hh:]mm:ss) | - |
| 文件描述符 | ls /proc/PID/fd | 打開的文件描述符數(shù)量 | 注意是否有泄漏 |
內(nèi)存相關(guān)指標詳解
- VIRT (Virtual Memory Size): 進程使用的虛擬內(nèi)存總量,包括代碼、數(shù)據(jù)、共享庫等
- RES (Resident Set Size): 進程實際使用的物理內(nèi)存,不包括交換分區(qū)
- SHR (Shared Memory): 共享內(nèi)存大小,可能被多個進程共享
- %MEM: RES 占系統(tǒng)總物理內(nèi)存的百分比
CPU 相關(guān)指標詳解
- %CPU: 進程在采樣周期內(nèi)的 CPU 使用百分比,可能超過 100%(多核系統(tǒng))
- 用戶態(tài)時間: 進程在用戶空間執(zhí)行的時間
- 內(nèi)核態(tài)時間: 進程在內(nèi)核空間執(zhí)行的時間(系統(tǒng)調(diào)用)
常見問題排查
1. CPU 使用率過高
診斷步驟:
# 查看 CPU 熱點函數(shù)
perf top -p PID
# 統(tǒng)計系統(tǒng)調(diào)用
strace -cp PID
# 查看線程 CPU 使用
top -H -p PID
# 使用 bpftrace 追蹤
bpftrace -e 'profile:hz:99 /pid == PID/ { @[ustack] = count(); }'
可能原因:
- 無限循環(huán)或死循環(huán)
- 頻繁的系統(tǒng)調(diào)用
- 計算密集型任務
- 鎖競爭導致的忙等待
2. 內(nèi)存使用過高
診斷步驟:
# 查看詳細內(nèi)存映射 pmap -x PID # 查看內(nèi)存使用趨勢 watch -n 1 'ps -p PID -o pid,%mem,rss,vsz' # 使用 gdb 查看內(nèi)存區(qū)域 gdb -p PID -ex "info proc mappings" --batch # 檢查內(nèi)存泄漏(需要持續(xù)監(jiān)控) valgrind --leak-check=full ./program
可能原因:
- 內(nèi)存泄漏
- 緩存過大
- 數(shù)據(jù)結(jié)構(gòu)設計不合理
- 內(nèi)存碎片
3. I/O 瓶頸
診斷步驟:
# 實時監(jiān)控 I/O
iotop -p PID
# 查看 I/O 統(tǒng)計
cat /proc/PID/io
# 使用 SystemTap 追蹤文件操作(需要 root)
stap -e 'probe vfs.* { if (pid() == PID) printf("%s\n", pp()) }'
# 查看磁盤使用情況
iostat -x 1
可能原因:
- 頻繁的小文件讀寫
- 未使用緩沖
- 磁盤性能瓶頸
- 網(wǎng)絡 I/O 延遲
4. 線程/進程過多
診斷步驟:
# 查看線程數(shù)量 ls /proc/PID/task | wc -l # 查看線程詳情 ps -T -p PID # 查看進程樹 pstree -p PID
5. 文件描述符泄漏
診斷步驟:
# 監(jiān)控文件描述符數(shù)量
watch -n 1 'ls /proc/PID/fd | wc -l'
# 查看打開的文件
lsof -p PID
# 查看具體文件類型分布
ls -l /proc/PID/fd | awk '{print $NF}' | xargs -I {} readlink {} | sort | uniq -c
自動化監(jiān)控腳本
綜合監(jiān)控腳本
創(chuàng)建一個綜合監(jiān)控腳本,定期采集進程的各項資源指標:
#!/bin/bash
# 進程資源監(jiān)控腳本
# 用法: ./monitor_process.sh <PID> [interval] [count]
if [ -z "$1" ]; then
echo "用法: $0 <PID> [刷新間隔(秒)] [監(jiān)控次數(shù)]"
echo "示例: $0 12345 2 10"
exit 1
fi
PID=$1
INTERVAL=${2:-2}
COUNT=${3:-5}
# 檢查進程是否存在
if ! kill -0 $PID 2>/dev/null; then
echo "錯誤: 進程 $PID 不存在"
exit 1
fi
echo "===== 進程 $PID 資源監(jiān)控 (每 ${INTERVAL} 秒刷新,共 ${COUNT} 次) ====="
echo ""
for i in $(seq 1 $COUNT); do
echo "--- 第 $i 次監(jiān)控 ($(date '+%Y-%m-%d %H:%M:%S')) ---"
# 基本信息
echo "【基本信息】"
ps -p $PID -o user,pid,ppid,ni,%cpu,%mem,vsz,rss,tty,stat,start,time,cmd --no-headers 2>/dev/null || echo "進程已結(jié)束"
# CPU 使用
if [ -f /proc/$PID/stat ]; then
echo -e "\n【CPU 使用】"
cat /proc/$PID/stat | awk '{
utime = $14
stime = $15
cutime = $16
cstime = $17
total = utime + stime + cutime + cstime
printf "用戶態(tài)CPU: %d 時鐘周期\n", utime
printf "內(nèi)核態(tài)CPU: %d 時鐘周期\n", stime
printf "子進程用戶態(tài): %d 時鐘周期\n", cutime
printf "子進程內(nèi)核態(tài): %d 時鐘周期\n", cstime
printf "總CPU時間: %d 時鐘周期\n", total
}'
fi
# 內(nèi)存使用
if [ -f /proc/$PID/status ]; then
echo -e "\n【內(nèi)存使用】"
grep -E 'VmPeak|VmSize|VmRSS|VmSwap|VmHWM|VmData|VmStk|VmExe' /proc/$PID/status
fi
# I/O 統(tǒng)計
if [ -f /proc/$PID/io ]; then
echo -e "\n【I/O 統(tǒng)計】"
cat /proc/$PID/io
fi
# 打開文件描述符
if [ -d /proc/$PID/fd ]; then
echo -e "\n【打開文件描述符數(shù)量】"
echo "$(ls -l /proc/$PID/fd 2>/dev/null | wc -l) 個"
fi
# 線程數(shù)
if [ -d /proc/$PID/task ]; then
echo -e "\n【線程數(shù)】"
echo "$(ls /proc/$PID/task 2>/dev/null | wc -l) 個"
fi
# 上下文切換
if [ -f /proc/$PID/status ]; then
echo -e "\n【上下文切換】"
grep -E 'voluntary_ctxt_switches|nonvoluntary_ctxt_switches' /proc/$PID/status
fi
echo ""
echo "=========================================="
echo ""
if [ $i -lt $COUNT ]; then
sleep $INTERVAL
fi
done
echo "監(jiān)控完成"
保存監(jiān)控數(shù)據(jù)腳本
#!/bin/bash
# 將監(jiān)控數(shù)據(jù)保存到文件
# 用法: ./save_monitor.sh <PID> <output_file> [interval]
PID=$1
OUTPUT=${2:-"monitor_${PID}_$(date +%Y%m%d_%H%M%S).log"}
INTERVAL=${3:-5}
echo "開始監(jiān)控進程 $PID,數(shù)據(jù)保存到 $OUTPUT"
echo "監(jiān)控間隔: ${INTERVAL} 秒,按 Ctrl+C 停止"
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 檢查進程是否存在
if ! kill -0 $PID 2>/dev/null; then
echo "[$TIMESTAMP] 進程已結(jié)束" >> "$OUTPUT"
break
fi
# 采集數(shù)據(jù)
{
echo "===== $TIMESTAMP ====="
ps -p $PID -o pid,%cpu,%mem,vsz,rss,cmd --no-headers
[ -f /proc/$PID/status ] && grep -E 'VmRSS|VmSize' /proc/$PID/status
[ -f /proc/$PID/io ] && cat /proc/$PID/io
echo ""
} >> "$OUTPUT"
sleep $INTERVAL
done
echo "監(jiān)控數(shù)據(jù)已保存到 $OUTPUT"
工具選擇建議
根據(jù)不同場景選擇合適的工具:
| 場景 | 推薦工具 | 說明 |
|---|---|---|
| 快速查看 | ps | 簡單快速,適合腳本集成 |
| 實時監(jiān)控 | htop 或 top | 交互式界面,適合手動監(jiān)控 |
| 詳細統(tǒng)計 | pidstat | 適合定期采樣和數(shù)據(jù)分析 |
| 歷史數(shù)據(jù) | sar | 查看歷史性能數(shù)據(jù),適合趨勢分析 |
| I/O 分析 | iotop | 專門用于 I/O 監(jiān)控 |
| 內(nèi)存分析 | pmap、smem | pmap 查看內(nèi)存映射,smem 提供更準確的內(nèi)存統(tǒng)計 |
| 網(wǎng)絡連接 | ss、lsof | ss 更現(xiàn)代快速,lsof 功能更全面 |
| 文件描述符 | lsof | 查看進程打開的文件和網(wǎng)絡連接 |
| 綜合監(jiān)控 | atop | 功能全面,適合系統(tǒng)管理員 |
| 性能分析 | perf 或 bpftrace | 適合深度性能調(diào)優(yōu) |
| 系統(tǒng)調(diào)用 | strace | 追蹤和統(tǒng)計系統(tǒng)調(diào)用 |
| 資源限制 | prlimit | 查看和設置進程資源限制 |
| CPU 親和性 | taskset、numactl | 查看和設置 CPU 綁定和 NUMA |
| 容器監(jiān)控 | docker stats、cgroup | 監(jiān)控容器資源使用 |
| systemd 服務 | systemd-cgtop | 監(jiān)控 systemd 管理的服務 |
| 自動化 | /proc 文件系統(tǒng) | 適合腳本和自動化工具 |
| 問題排查 | strace + perf + pmap | 綜合工具定位性能問題 |
總結(jié):分析 Linux 進程資源占用有多種方法,選擇合適的工具可以事半功倍:
常用方法分類
日常監(jiān)控:
- 實時監(jiān)控:
htop、top、atop - 快照查看:
ps、pidstat - 歷史數(shù)據(jù):
sar(需啟用 sysstat 數(shù)據(jù)收集)
專項分析:
- 內(nèi)存:
pmap(內(nèi)存映射)、smem(準確統(tǒng)計)、/proc/PID/smaps(詳細映射) - I/O:
iotop、pidstat -d、/proc/PID/io - 網(wǎng)絡:
ss、lsof -i、netstat - 文件:
lsof、/proc/PID/fd
腳本集成:
/proc文件系統(tǒng):最底層的信息源,適合自動化ps命令:簡單快速,輸出格式統(tǒng)一pidstat:適合定期采樣
性能分析:
perf:功能強大的性能分析工具bpftrace:動態(tài)追蹤,靈活強大strace:系統(tǒng)調(diào)用追蹤
容器和服務監(jiān)控:
- Docker:
docker stats、cgroup 文件系統(tǒng) - systemd:
systemd-cgtop、systemctl status - Cgroup:
/sys/fs/cgroup/文件系統(tǒng)
系統(tǒng)級監(jiān)控:
vmstat:系統(tǒng)整體資源統(tǒng)計sar:歷史性能數(shù)據(jù)slabtop:內(nèi)核緩存監(jiān)控
關(guān)鍵指標
- CPU:
%cpu、用戶態(tài)/內(nèi)核態(tài)時間、CPU 親和性 - 內(nèi)存:
RSS(物理內(nèi)存)、VSZ(虛擬內(nèi)存)、PSS(比例集大?。?nèi)存映射 - I/O:
read_bytes、write_bytes、I/O 速率 - 網(wǎng)絡: 連接數(shù)、連接狀態(tài)、端口占用
- 其他: 線程數(shù)、文件描述符數(shù)、上下文切換次數(shù)、資源限制
最佳實踐
- 定期監(jiān)控:建立監(jiān)控機制,定期采集關(guān)鍵指標
- 建立基線:記錄正常情況下的資源使用,便于對比
- 組合使用:根據(jù)問題類型組合使用多個工具
- 自動化:使用腳本自動化監(jiān)控和告警
- 歷史數(shù)據(jù):啟用
sar數(shù)據(jù)收集,便于問題回溯 - 容器環(huán)境:在容器環(huán)境中使用 cgroup 相關(guān)工具
問題排查流程
- 快速定位:使用
htop或top快速查看資源占用 - 詳細分析:使用
pidstat、pmap等工具深入分析 - 性能分析:使用
perf、strace定位性能瓶頸 - 歷史對比:使用
sar查看歷史數(shù)據(jù),分析趨勢 - 綜合診斷:結(jié)合多個工具的結(jié)果,全面分析問題
定期監(jiān)控和記錄這些指標,有助于及時發(fā)現(xiàn)和解決性能問題。根據(jù)具體場景選擇合適的工具組合,可以更高效地完成資源分析和問題排查。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Linux+Apache服務器URL區(qū)分大小寫問題
Linux服務器的大小寫敏感有時候很不方便,在地址欄里一定要輸入準確的URL才能訪問,對搜索引擎和用戶不是很友好,那么如何解決LINUX服務器URL的大小寫問題2020-01-01
在Linux環(huán)境下安裝和使用Pyenv的詳細指南
Pyenv是一個用于管理多個Python版本的強大工具,特別適合在Linux環(huán)境下使用,本文將詳細介紹如何在Linux系統(tǒng)上安裝和使用Pyenv,以便更好地管理Python開發(fā)環(huán)境,需要的朋友可以參考下2025-03-03
centos 6.5下修改SSH端口及禁用root遠程登錄的方法
Linux各發(fā)行版中SSH端口默認為22,如果正式做站或其它用途,為了提高安全性就需要修改掉默認的SSH端口號,防止被有心人窮舉密碼。這篇文章主要給大家介紹了在centos 6.5系統(tǒng)下修改SSH端口及禁用root遠程登錄的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02
在Linux系統(tǒng)下更換Git項目倉庫源地址的多種方法
在Linux系統(tǒng)中更換Git項目倉庫的源地址有多種方法,包括使用git remote命令、直接修改配置文件和使用SSH協(xié)議,每種方法都有其適用場景和操作步驟,需要的朋友可以參考下2025-10-10
在VM虛擬機中CentOS7安裝VMware Tools全過程
這篇文章主要介紹了在VM虛擬機中CentOS7安裝VMware Tools全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
在Linux中刪除超大(100-200GB)文件的實現(xiàn)方式
這篇文章主要介紹了在Linux中刪除超大(100-200GB)文件的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04

