4.3.5 性能与诊断工具(strace、perf、pmap)
性能与诊断工具用于定位系统调用瓶颈、CPU热点与内存布局问题。本节以 strace、perf、pmap 为核心,给出原理草图、安装方式、命令解释、排错与练习,形成可复用的排查路径。
安装与依赖检查(适用多发行版)
- Debian/Ubuntu:
sudo apt update
sudo apt install -y strace linux-tools-common linux-tools-$(uname -r) pmap
# pmap 通常来自 procps
sudo apt install -y procps
- CentOS/RHEL:
sudo yum install -y strace perf procps-ng
# 若内核工具包缺失,可安装:
sudo yum install -y kernel-tools kernel-tools-libs
- 验证:
strace -V
perf --version
pmap -V
strace:系统调用与阻塞定位
- 原理:通过 ptrace 拦截进程系统调用并输出参数与耗时。
sequenceDiagram
participant P as 进程
participant K as 内核
participant S as strace
S->>P: 附加/启动跟踪
P->>K: 发起系统调用
K-->>S: 返回参数/耗时/错误码
- 常用方式与命令解释:
# 跟踪新进程并输出到文件,-f 跟踪子进程
strace -f -o /tmp/trace.log /usr/bin/curl https://example.com
# 附加到运行中进程,-p 指定 PID
strace -f -p 1234
# 统计系统调用耗时,-c 汇总
strace -c -p 1234 -- sleep 10
# 过滤调用,只看 open/read/write
strace -e trace=open,read,write -p 1234
- 典型示例与预期效果:
# 示例:定位“连接慢”的进程
strace -f -tt -T -p 1234
# -tt 输出精确时间戳,-T 输出每个调用耗时
# 预期:发现 connect() 或 poll()/epoll_wait() 长时间阻塞
- 排错要点:
1. 大量futex或epoll_wait长时间阻塞 → 可能线程等待或事件未就绪。
2.open/stat返回ENOENT→ 路径错误;返回EACCES→ 权限问题。
3. 若输出过大,缩短时间或加过滤条件:-e trace=network。 - 练习:
- 启动一个
curl,用strace找出 DNS 解析与连接耗时调用。 - 附加到 Nginx worker,过滤
accept/read/write并观察频率。
perf:CPU热点与性能剖析
- 原理:基于内核采样事件(PMU)收集指令/函数热点。
- 常用方式与命令解释:
# 实时热点,-p 指定进程
perf top -p 1234
# 记录 30 秒,-g 采集调用栈
perf record -g -p 1234 -- sleep 30
perf report
# 系统级采样
perf record -a -g -- sleep 30
# 统计事件(上下文切换/分支失败等)
perf stat -p 1234 -- sleep 10
- 典型示例与预期效果:
# 记录并生成火焰图(需安装 FlameGraph)
perf record -g -p 1234 -- sleep 30
perf script > /tmp/out.perf
# 预期:找到占用 CPU 最高的函数/库
- 排错要点:
1.perf report显示unknown→ 安装调试符号或开启符号解析。
2. 采样权限不足 → 提升权限或设置/proc/sys/kernel/perf_event_paranoid。
3. CPU 热点在内核函数 → 可能系统调用或调度开销高。 - 练习:
- 对一个 CPU 升高的进程执行
perf top,记录前三热点函数。 - 运行
perf stat比较不同负载下的上下文切换次数。
pmap:进程内存布局与泄漏线索
- 原理:读取 /proc/<pid>/maps 展示内存映射与 RSS。
- 常用方式与命令解释:
# 显示内存映射
pmap 1234
# 显示详细信息(RSS/Dirty)
pmap -x 1234
# 详细并按地址排序
pmap -X 1234
- 典型示例与预期效果:
# 连续采样,观察堆是否增长
pmap -x 1234 | awk 'END{print "TOTAL RSS:", $4, "KB"}'
sleep 5
pmap -x 1234 | awk 'END{print "TOTAL RSS:", $4, "KB"}'
# 预期:RSS 持续增长提示内存泄漏可能
- 排错要点:
1.anon段快速增长 → 可能堆内存分配过多。
2.stack异常大 → 可能递归或线程栈过大。
3.shared增长 → 关注共享库或 mmap 文件。 - 练习:
- 写一个简单脚本循环申请内存,使用
pmap -x观察 RSS 变化。 - 结合
pmap -x和应用日志,确认增长段与业务操作关联。
组合使用建议
1. 先用 strace 判断是否阻塞在系统调用层或路径/权限错误。
2. 再用 perf 定位 CPU 热点函数与调用栈。
3. 使用 pmap 查看内存映射与 RSS 变化,判断泄漏方向。
4. 输出一份诊断记录:命令、关键输出、结论与优化建议,形成可复用排查模板。