在 Linux 系統上,有時需要找出執行時間過長或佔用資源過多的程序,例如排查效能瓶頸、清理僵屍程序,或是終止卡住的任務。以下整理幾種常用方法。
使用 ps 查看程序執行時間
查看所有程序並依 CPU 排序
1
|
ps aux --sort=-%cpu | head -20
|
欄位說明:
USER:程序擁有者
PID:程序 ID
%CPU:CPU 使用率
%MEM:記憶體使用率
ELAPSED / TIME:累積 CPU 時間
查看程序的實際執行時間(elapsed time)
1
|
ps -eo pid,etime,cmd --sort=-etime | head -20
|
etime:程序從啟動到現在的經過時間,格式為 [[dd-]hh:]mm:ss
--sort=-etime:依執行時間降冪排序(最久的在最前面)
例如找出執行超過 1 小時的程序:
1
2
3
4
5
6
7
|
ps -eo pid,etime,cmd | awk '{
split($2, t, "[-:]")
if (length(t) == 4) hours = t[2]
else if (length(t) == 3) hours = t[1]
else hours = 0
if (hours+0 >= 1) print $0
}'
|
使用 top / htop 即時監控
top
常用互動快捷鍵:
P:依 CPU 排序
M:依記憶體排序
k:輸入 PID 終止程序
q:離開
htop(需另外安裝)
1
2
|
sudo apt install htop # Debian/Ubuntu
htop
|
htop 提供更友善的彩色介面,可用方向鍵選擇程序,F9 送訊號,F10 離開。
透過 /proc 目錄查詢
Linux 的 /proc 目錄包含所有程序的即時資訊。/proc/<pid>/stat 中記錄了程序的啟動時間(以系統開機後的時鐘滴答數計算)。
1
2
|
# 查看 PID 1234 的啟動時間(滴答數)
cat /proc/1234/stat | awk '{print $22}'
|
搭配 getconf CLK_TCK(通常為 100)和 /proc/uptime 可計算出實際執行時間:
1
2
3
4
5
6
7
|
pid=1234
clk_tck=$(getconf CLK_TCK)
uptime_sec=$(awk '{print int($1)}' /proc/uptime)
start_ticks=$(awk '{print $22}' /proc/$pid/stat)
start_sec=$((start_ticks / clk_tck))
elapsed=$((uptime_sec - start_sec))
echo "程序 $pid 已執行 $elapsed 秒"
|
找出執行超過 N 分鐘的程序
結合 find 和 /proc,找出所有數字命名的目錄(即程序目錄):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
find /proc -maxdepth 1 -type d -name '[0-9]*' | while read dir; do
pid=$(basename $dir)
if [ -f "$dir/stat" ]; then
start_ticks=$(awk '{print $22}' "$dir/stat" 2>/dev/null)
clk_tck=$(getconf CLK_TCK)
uptime_sec=$(awk '{print int($1)}' /proc/uptime)
elapsed=$(( uptime_sec - start_ticks / clk_tck ))
if [ "$elapsed" -gt 300 ]; then # 超過 300 秒(5 分鐘)
cmd=$(cat "$dir/cmdline" 2>/dev/null | tr '\0' ' ')
echo "PID=$pid elapsed=${elapsed}s cmd=$cmd"
fi
fi
done
|
參考資料