内存碎片化八
是的,perf 可以用来分析系统的性能瓶颈,并帮助判断 CPU 密集、I/O 密集、锁争用 或 内存压力。你可以使用 perf 的不同子命令来深入分析具体问题。以下是详细的 perf 分析方法:
🔍 使用 perf 进行系统负载分析
如果系统本身无法明确分出 CPU 密集、I/O 密集、锁争用还是内存问题,我们可以用 perf 进行深入分析。
1️⃣ perf top:快速查看热点函数
perf top
示例:
40.00% [kernel] [k] __schedule
20.00% mysqld [.] btr_search_info_update
15.00% nginx [.] ngx_http_gzip_filter
10.00% [kernel] [k] do_page_fault
分析:
-
__schedule占比高(40%) → 可能是 锁争用 或 进程切换过多。 -
ngx_http_gzip_filter高(15%) →nginx可能在 进行 gzip 压缩,占用 CPU。 -
do_page_fault高(10%) → 可能是 内存不足,导致频繁换页。
2️⃣ perf record + perf report:记录并分析热点
perf record -F 99 -a -g -- sleep 30
perf report
-
-F 99:设置采样频率为 99 Hz -
-a:监视所有 CPU -
-g:记录调用栈 -
sleep 30:记录 30 秒
示例:
30.00% [kernel] [k] __schedule
- __schedule
- 20% do_futex
- 15% futex_wait
- 10% pthread_mutex_lock
分析:
-
大量
futex_wait→ 进程等待锁,可能是多线程锁争用问题。
3️⃣ perf stat:整体性能概览
perf stat -a -d sleep 10
示例:
Performance counter stats for 'system wide':
500.0 msec task-clock # 50.000 CPUs utilized
1,000 context-switches # 10.0 K/sec
500 CPU-migrations # 5.0 K/sec
200 page-faults # 2.0 K/sec
2,000,000,000 cycles # 4.0 GHz
1,000,000,000 stalled-cycles-frontend # 50.00% frontend cycles idle
800,000,000 stalled-cycles-backend # 40.00% backend cycles idle
1,500,000,000 instructions # 0.75 insn per cycle
500,000,000 branches # 1.0 M/sec
10,000 branch-misses # 1.0 % of all branches
分析:
-
stalled-cycles-frontend高(50%) → 可能是 I/O 瓶颈,CPU 等待数据。 -
context-switches高(> 10K/sec) → 可能是 线程调度频繁,锁争用严重。 -
page-faults高 → 可能是 内存压力导致的换页。
4️⃣ perf sched:查看调度和锁争用
perf sched record
sleep 5
perf sched latency
示例:
PID Command Switches Avg wait
1234 python 200 10.5 ms
5678 java 500 30.2 ms
分析:
-
Avg wait高 → 进程可能 等待 CPU 或锁。
5️⃣ perf mem:分析内存瓶颈
perf mem record -a
perf mem report
如果 perf mem report 结果中 LLC misses(Last Level Cache Misses)很高:
-
可能是 CPU 频繁访问主存,内存带宽成为瓶颈。
-
可能是 数据未正确对齐,导致性能下降。
📌 总结:如何判断负载类型
| 负载类型 | perf 现象 | 可能原因 | 解决方案 |
|---|---|---|---|
| CPU 密集 | perf top 显示用户态 us% 高 |
计算任务、死循环 | 优化代码、检查线程 |
| I/O 密集 | stalled-cycles-frontend 高 |
磁盘或网络 I/O | 监控 iostat,优化磁盘 I/O |
| 锁争用 | __schedule 高,perf sched futex_wait 高 |
多线程同步问题 | 调整锁机制 |
| 内存压力 | do_page_fault 高,perf mem LLC misses 高 |
OOM、缓存过大 | 降低进程内存占用 |
你可以结合 perf 进行分析,最终精准找到问题点!🚀
如果系统 负载高,但 无法确定是 CPU 密集、I/O 瓶颈、锁争用还是内存压力,可以使用 perf 进行系统化分析,分步骤定位问题。
🔍 perf 定位问题的系统化方法
1️⃣ 先观察整体系统状态
先使用 系统级工具 获取一个大致的方向:
vmstat 1
示例输出:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 10240 20000 500000 0 0 200 300 500 1000 30 5 60 5 0
关键字段分析:
-
r高(运行队列) → CPU 可能是瓶颈。 -
b高(阻塞进程) → 可能是 I/O 问题或锁争用。 -
wa%高(I/O 等待) → 磁盘 I/O 可能是瓶颈。 -
free低,si/so高(交换分区活动) → 内存压力大。
2️⃣ perf top:查看当前 CPU 占用热点
perf top
如果 perf top 显示如下情况,可以判断问题类型:
-
用户态(us%)高,且
perf top中热点函数属于mysqld,python,java→ CPU 计算密集 🏋️。 -
内核态(sy%)高,
perf top主要显示__schedule,futex_wait,mutex_lock→ 锁争用问题 🔐。 -
bio_*,ext4_*,nvme_*高 → I/O 瓶颈 💾。
3️⃣ perf stat:监控 CPU、I/O、锁争用
perf stat -a -d sleep 10
示例输出:
Performance counter stats for 'system wide':
1,000,000,000 cycles # 4.0 GHz
200,000,000 instructions # 0.20 insn per cycle
10,000,000 LLC-load-misses # 50% last-level cache miss
800,000,000 stalled-cycles-frontend # 80% frontend stalled
500,000,000 stalled-cycles-backend # 50% backend stalled
20,000,000 context-switches # 2.0 M/sec
5,000,000 page-faults # 500 K/sec
分析:
-
stalled-cycles-frontend高(>50%) → CPU 在等数据,可能是 I/O 瓶颈。 -
context-switches高(>10K/sec) → 锁争用问题。 -
LLC-load-misses高 → CPU 受缓存未命中影响,可能是 内存瓶颈。 -
instructions per cycle (IPC)低(< 1.0) → CPU 可能因 I/O 等待而低效。
4️⃣ perf record + report:记录具体热点
如果 perf top 发现 __schedule, bio_*, nvme_*, futex_wait,可以用 perf record 进行详细分析:
perf record -a -g -- sleep 30
perf report
示例:
40.00% [kernel] [k] __schedule
- 20% futex_wait
- 15% pthread_mutex_lock
20.00% mysqld [.] btr_search_info_update
10.00% [kernel] [k] do_page_fault
解读:
-
futex_wait高 → 线程锁争用,优化pthread_mutex。 -
do_page_fault高 → 可能是内存压力大,导致频繁换页。 -
btr_search_info_update(MySQL) → 数据库索引更新导致 CPU 过载。
5️⃣ perf sched:锁争用分析
如果 perf top 发现 __schedule 高,可以用 perf sched 看进程调度情况:
perf sched record
sleep 5
perf sched latency
示例:
PID Command Switches Avg wait
1234 nginx 500 30.2 ms
5678 java 200 10.5 ms
-
Avg wait高 → 进程可能 等待锁或 CPU。
6️⃣ perf mem:内存访问瓶颈
perf mem record -a
perf mem report
如果 perf mem report 结果中 LLC misses 高:
-
可能是 CPU 频繁访问主存,内存带宽成为瓶颈。
📌 总结:如何精准定位问题
| 负载类型 | perf 现象 | 可能原因 | 解决方案 |
|---|---|---|---|
| CPU 密集 | perf top 用户态 us% 高 |
计算任务、死循环 | 优化代码、检查线程 |
| I/O 瓶颈 | stalled-cycles-frontend 高 |
磁盘或网络 I/O | 监控 iostat,优化 I/O |
| 锁争用 | __schedule 高,perf sched futex_wait 高 |
多线程同步问题 | 调整锁机制 |
| 内存压力 | do_page_fault 高,perf mem LLC misses 高 |
OOM、缓存过大 | 降低进程内存占用 |
你可以按这个流程逐步分析系统负载,最终精准找到问题点!🚀
浙公网安备 33010602011771号