内存碎片化八

是的,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, javaCPU 计算密集 🏋️。

  • 内核态(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-missesCPU 受缓存未命中影响,可能是 内存瓶颈

  • 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、缓存过大 降低进程内存占用

你可以按这个流程逐步分析系统负载,最终精准找到问题点!🚀

posted on 2025-04-01 14:01  吃草的青蛙  阅读(106)  评论(0)    收藏  举报

导航