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. 大量 futexepoll_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. 输出一份诊断记录:命令、关键输出、结论与优化建议,形成可复用排查模板。