操作系统学习笔记 · 第 30 课 · Linux 实操——用命令"解剖"操作系统
前面二十九课,我们把操作系统从"进程"一路学到了"容器",理论齐了。但真正的高手,不只是"懂原理",更要会动手排障——系统卡了、内存满了、程序挂了,你能定位问题在哪吗?这一课,我们学一套"用命令解剖操作系统"的硬功夫。这是第九阶段(实战收束)的第一课,也是最"实用"的一课。
从"体检"说起
人身体不舒服,医生会做体检:量血压、验血、拍片,一步步定位病灶。
系统也一样。它"不舒服"时(变慢、卡死、内存告警),你也要给它做体检:看负载、看内存、看进程、看系统调用。这一课,就是教你做这套体检,并建立一条"出问题 → 定位 → 处置"的排查思路。
30.1 负载与 CPU:top / uptime / vmstat
一句话理解:load average(1/5/15 分钟平均负载)表示"正在运行 + 等待运行的进程数",持续高于 CPU 核数就说明"忙不过来了"。打开 top 或 uptime,第一行就能看到:
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 -h看available而不是只看free——Linux 会把空闲内存拿去做缓存,available才是"还能给程序用的量"。
free -h 输出里,最容易被误解的是 free 和 buff/cache:
free很小、buff/cache很高,是正常的——Linux 会把空闲内存拿去做页缓存(第 21 课讲过),"看着满"其实是在干活;- 真正该看的是
available:"还能给新程序用的量"。这个值接近 0,且开始 swap(换到磁盘),才是真的危险。
再配合 vmstat 1 3:
si/so:swap 进/出,如果持续非 0,说明内存不够、正在频繁换页(还记得第 17 课的抖动吗?系统会变得极慢)。
一句话:看内存别被free骗了,盯available和si/so。
30.3 进程在干什么:ps / lsof / strace
一句话理解:ps aux看进程状态,lsof -p PID看它打开了哪些文件/连接,strace -p PID看它正在发什么系统调用——三个命令组合等于"给进程做体检 + 录音"。
找到可疑进程后,三个命令层层深入:
ps aux:看所有进程的状态——谁在吃 CPU、吃内存;lsof -p PID:看这个进程打开了哪些文件、网络连接(还记得"一切皆文件"吗?);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 排查思路(万能四步)
把前面的命令串成一条标准排查流程:
top/uptime看负载——CPU 还是 I/O 满?vmstat/iostat定位瓶颈类型(CPU?内存?磁盘?);ps/lsof找到"元凶"进程;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高于核数 = 忙不过来,vmstat看r/cs; - 内存:看
available而非free,si/so判断是否 swap; - 进程:
ps找元凶 →lsof看资源 →strace看系统调用; - 性能:
perf+ 火焰图,找热点函数; - 万能四步:看负载 → 定位瓶颈 → 找进程 → 钻进去。
留三个问题:
load average持续高于 CPU 核数意味着什么?- 为什么看内存要看
available而不是free? - 程序卡住时,
strace能帮你发现什么?
到这里,你的"工具箱"里已经塞满了命令。但还有一个问题悬而未决:你天天敲命令的那个 shell,内部到底是怎么工作的? 它怎么把你敲的 ls -l | grep txt > out.txt 拆解、执行?答案,就在下一课——我们亲手用 C 写一个迷你 shell,把全书知识(fork/exec、管道、重定向、信号)合流成一个能跑的真程序。这是全书的最后一课。