前面二十九课,我们把操作系统从"进程"一路学到了"容器",理论齐了。但真正的高手,不只是"懂原理",更要会动手排障——系统卡了、内存满了、程序挂了,你能定位问题在哪吗?这一课,我们学一套"用命令解剖操作系统"的硬功夫。这是第九阶段(实战收束)的第一课,也是最"实用"的一课。

从"体检"说起

人身体不舒服,医生会做体检:量血压、验血、拍片,一步步定位病灶。

系统也一样。它"不舒服"时(变慢、卡死、内存告警),你也要给它做体检:看负载、看内存、看进程、看系统调用。这一课,就是教你做这套体检,并建立一条"出问题 → 定位 → 处置"的排查思路


30.1 负载与 CPU:top / uptime / vmstat

一句话理解load average(1/5/15 分钟平均负载)表示"正在运行 + 等待运行的进程数",持续高于 CPU 核数就说明"忙不过来了"。

打开 topuptime,第一行就能看到:

load average: 2.50, 1.80, 1.20

这三个数字,分别是过去 1 分钟、5 分钟、15 分钟的平均负载。它代表"正在运行 + 等待运行的进程数"。

判断标准:

  • 4 核机器,load 长期 > 4,说明任务在排队,忙不过来了;
  • load 低,说明机器有空闲。

再配合 vmstat 1(每秒采样一次):

  • r就绪队列长度(等着 CPU 的进程数),持续高说明 CPU 是瓶颈;
  • cs上下文切换次数,过高说明大量进程抢 CPU,可能有调度问题。
一句话:先看 load 判断"忙不忙",再看 r/cs 判断"是不是 CPU 瓶颈"。

30.2 内存水位:free / vmstat

一句话理解free -havailable 而不是只看 free——Linux 会把空闲内存拿去做缓存,available 才是"还能给程序用的量"。

free -h 输出里,最容易被误解的是 freebuff/cache

  • free 很小、buff/cache 很高,是正常的——Linux 会把空闲内存拿去做页缓存(第 21 课讲过),"看着满"其实是在干活;
  • 真正该看的是 available"还能给新程序用的量"。这个值接近 0,且开始 swap(换到磁盘),才是真的危险。

再配合 vmstat 1 3

  • si / soswap 进/出,如果持续非 0,说明内存不够、正在频繁换页(还记得第 17 课的抖动吗?系统会变得极慢)。
一句话:看内存别被 free 骗了,盯 availablesi/so

30.3 进程在干什么:ps / lsof / strace

一句话理解ps aux 看进程状态,lsof -p PID 看它打开了哪些文件/连接,strace -p PID 看它正在发什么系统调用——三个命令组合等于"给进程做体检 + 录音"。

找到可疑进程后,三个命令层层深入:

  1. ps aux:看所有进程的状态——谁在吃 CPU、吃内存;
  2. lsof -p PID:看这个进程打开了哪些文件、网络连接(还记得"一切皆文件"吗?);
  3. strace -p PID:看它正在发什么系统调用——等于给进程"录音"。
例子:程序卡住了,strace -p PID 一看——它卡在 read 就是等 I/O,卡在 futex 就是等锁(第 13 课的锁)。立刻知道病根在哪。

30.4 性能分析:perf 与火焰图

一句话理解perf record 采样"CPU 时间花在哪",生成火焰图(flame graph)一眼看出热点函数——火焰图的横向宽度代表耗时占比,越宽越热。

程序"慢"但不知道慢在哪?用 perf 采样:

perf top                       # 实时看哪个函数最耗 CPU
perf record -g ./your_program  # 采样 + 记录调用栈
perf report                    # 看调用树

把采样结果画成火焰图(flame graph)

火焰图从上往下是调用栈,横向宽度 = 采样到的 CPU 占比。找"又宽又平的塔",就是热点函数。

一句话:火焰图越宽 = 越热 = 越值得优化。


30.5 排查思路(万能四步)

把前面的命令串成一条标准排查流程:

  1. top / uptime 看负载——CPU 还是 I/O 满?
  2. vmstat / iostat 定位瓶颈类型(CPU?内存?磁盘?);
  3. ps / lsof 找到"元凶"进程;
  4. strace / perf 钻进去,看它到底卡在哪、时间花在哪。

这四步就是"系统排障的标准套路",从宏观到微观,层层收窄。练熟了,就敢在生产环境排障。


动手实验:造一个"病人",然后解剖它

# 制造负载 + 逐步解剖
yes > /dev/null &                     # 造一个 CPU 密集进程
P=$!
top -bn1 | head -8                    # 看 load、CPU 使用
ps -p $P -o pid,pcpu,pmem,stat,cmd    # 看这个进程状态
lsof -p $P                            # 它打开了什么
strace -p $P -c &                     # 统计它的系统调用
sleep 3; kill $P

# 内存水位
free -h                               # 注意 available vs free
vmstat 1 3                            # 看 si/so(swap 进出)、r、cs

# perf 热点(需装 linux-tools)
perf top                              # 实时热点
perf record -g ./your_program && perf report
一句话理解:这套命令就是"给操作系统做体检"的听诊器,练熟了就敢在生产环境排障。

试试:yes > /dev/null & 会造一个吃满单核的死循环进程。用 top 看它 %CPU 接近 100,ps -p 看它的状态,strace -p 看它疯狂调 write——一个完整的"解剖"流程就走通了。


深入点:两个进阶话题

① 火焰图读法

从上往下是调用栈,横向宽度 = 采样到的 CPU 占比,找"又宽又平的塔"就是热点。生成命令:
perf script | stackcollapse-perf.pl | flamegraph.pl > out.svg

② I/O 等待 vs CPU 忙

一个经典误判:load 很高,就以为要加 CPU。但要看 top 里的 wa(I/O 等待):

load 高但 CPU 空闲(us+sy 低),往往是大量进程卡在 I/O 上wa 高)。此时加 CPU 没用,要优化磁盘或程序。

一句话:先分清是"CPU 忙"还是"I/O 等",再动手,否则方向全错。


小结与思考题

这一课,我们学会了"解剖操作系统":

  • 负载load average 高于核数 = 忙不过来,vmstatr/cs
  • 内存:看 available 而非 freesi/so 判断是否 swap;
  • 进程ps 找元凶 → lsof 看资源 → strace 看系统调用;
  • 性能perf + 火焰图,找热点函数;
  • 万能四步:看负载 → 定位瓶颈 → 找进程 → 钻进去。

留三个问题:

  1. load average 持续高于 CPU 核数意味着什么?
  2. 为什么看内存要看 available 而不是 free
  3. 程序卡住时,strace 能帮你发现什么?
到这里,你的"工具箱"里已经塞满了命令。但还有一个问题悬而未决:你天天敲命令的那个 shell,内部到底是怎么工作的? 它怎么把你敲的 ls -l | grep txt > out.txt 拆解、执行?答案,就在下一课——我们亲手用 C 写一个迷你 shell,把全书知识(fork/exec、管道、重定向、信号)合流成一个能跑的真程序。这是全书的最后一课。

标签: 计算机基础, 操作系统, Linux

添加新评论