4.4.12. 系统性能优化指导
4.4.12.1. 概述
在
性能问题产生原因分析
在
CPU 性能问题产生的原因
高
负载 任务 过多 系统
中 运行 了 过 多 的 高 负载 任务,导致 CPU 使用率 接近 100%。例如,某些 计算 密集型 任务(如 数据处理、图像 渲染)占用 大量 CPU 时间。 解决
方法 :优化关键 任务 的 代码,减少 计算 复杂度;使用 多线程 或 多 进程 技术 分散 任务 负载;调整 进程 优先级,确保 关键 任务 优先 运行。
上下文
切换 频繁 系统
中 存在 大量 线程 或 进程,频繁 切换 导致 CPU 时间 浪费 在 上下文 切换 上,降低 了 实际 处理 任务 的 时间。 解决
方法 :减少不必要 的 线程 和 进程 数量;优化 线程 同步 机制,减少 锁 竞争;使用 无锁 编程技术。
中断
处理 过多 硬件
中断 频繁,导致 CPU 花费 大量 时间 处理 中断请求,影响 正常 任务 的 执行。例如,网络设备 或 磁盘 设备 的 中断 过多。 解决
方法 :优化硬件 设备 的 中断 处理 机制,如 调整 中断 触发 方式(电平 触发 或 边沿 触发);使用 中断 合并 技术 减少 中断 频率。
内存性能问题产生的原因
内存不足
系统
中 运行 了 过 多 占用 内存 的 任务,导致 物理 内存 耗尽,频繁 使用 swap 空间,降低 系统 性能。 解决
方法 :优化应用程序,减少 不必要 的 内存 分配;使用 内存 池 技术 管理 动态内存;合理配置 swap 空间,避免 过度 依赖 swap;考虑 更换 更 大容量 的 内存 器件。
内存
碎片 频繁
的 内存 分配 和 释放 导致 内存 碎片 化,影响 大块 内存 的 分配 效率。 解决
方法 :使用大页 内存( Huge Pages)减少 页表 开销;优化 内存 分配 策略,尽量减少 小 块内存 分配。
缓存
策略 不合理 内核
缓存 策略(如 文件 缓存、磁盘 缓存)配置 不合理,导致 缓存 命中率 低,增加 磁盘 I/O 操作。 解决
方法 :调整内核 缓存 参数,如 vm.dirty_ratio和vm.dirty_background_ratio;优化文件系统 缓存 策略。
OOM(Out of Memory)问题
系统
内存不足 时, OOM Killer 随机 杀死 进程,导致系统 不 稳定。 解决
方法 :合理配置 OOM Killer 的行为,如 调整 vm.overcommit_memory和vm.overcommit_ratio参数;监控内存 使用 情况,及时发现 内存不足 的 问题。
磁盘性能问题产生的原因
I/O 阻塞
磁盘 I/O 操作
频繁,导致系统 等待 I/O 操作 的 时间 过长。例如,大量文件 读写操作 或 磁盘 性能 不足。 解决
方法 :优化文件系统,选择 适合 嵌入式 设备 的 文件系统(如 F2FS、 JFFS2 );调整 I/O 调度 算法(如 Deadline 或 CFQ);使用 异步 I/O( AIO)技术 减少 阻塞。
文件系统
碎片 文件系统
使用 时间 过长,导致 文件 碎片 化,影响 文件 读写 速度。 解决
方法 :定期进行 文件系统 碎片 整理;使用 支持 在线 碎片 整理 的 文件系统。
磁盘
性能 不足 磁盘
设备 性能 不足,无法 满足 系统 需求。例如,使用 了 低速 的 机械 硬盘 或 闪存 设备。 解决
方法 :升级磁盘 设备,如 使用 SSD 替代 机械 硬盘。
文件系统
选择 不当 使用
的 文件系统 不 适合 嵌入式 设备 的 使用 场景,导致 性能 问题。例如,使用 传统 的 ext3 文件系统 在 闪存 设备 上 可能 导致 频繁 的 擦写 操作,降低 性能。 解决
方法 :根据设备 特点 选择 合适 的 文件系统,如 F2FS 适用 于 闪存 设备, XFS 适用 于 大 文件 存储。
网络性能问题产生的原因
网络带宽
不足 网络带宽
有限,无法 满足 系统对 网络 数据传输 的 需求。例如,高 并发 的 网络 请求 导致 网络 拥塞。 解决
方法 :升级网络设备,如 使用 更 高带宽 的 网卡 或 交换机;优化 网络拓扑 结构,减少 网络 延迟。
TCP 参数
配置 不合理 TCP 参数(如
tcp_max_syn_backlog、tcp_tw_reuse)配置不合理,导致 网络连接 建立 和 释放 效率 低下。 解决
方法 :调整 TCP 参数,优化网络连接 性能;使用 TCP 快速 打开( TFO)技术 减少 连接 建立 时间。
网络连接
过多 系统
中 存在 大量 未 关闭 的 网络连接,导致 系统资源 耗尽。例如,僵尸 连接 占用 大量 端口 资源。 解决
方法 :调整系统 最大 文件 句柄 数( ulimit -n);优化应用程序,及时 关闭 无用 的 网络连接。
中断
处理 问题 网络设备
中断 处理不当,导致 网络 数据包 丢失 或 延迟 增加。 解决
方法 :优化网络设备 的 中断 处理 机制,如 调整 中断 触发 方式;使用 RPS(接收 队列 缩放)和 RFS(接收 流 转向)技术 提高 多核 CPU 的 网络 处理 能力。
系统配置问题产生的原因
内核
配置 不合理 内核
中 包含 不必要 的 模块 和 功能,增加 了 系统启动 时间 和 运行 开销。 解决
方法 :裁剪内核,移除 不必要 的 模块 和 功能;根据 实际 需求 定制 内核 配置。
系统
服务 过多 系统
中 运行 了 过 多 不必要 的 服务,占用 系统资源,影响 系统 性能。 解决
方法 :关闭不必要 的 系统 服务 和 守护 进程;优化 系统 服务 的 启动 顺序 和 参数 配置。
资源
限制 不合理 系统资源
限制(如 内存 限制、文件 句柄 限制)设置 不合理,导致 应用程序 无法 正常 运行。 解决
方法 :根据实际 需求 调整 系统资源 限制 参数;监控 资源 使用 情况,避免 资源 耗尽。
安全策略
影响 安全策略(如 SELinux、防火墙
规则)过于 严格,导致系统 性能 下降。例如,防火墙 规则 限制 了 某些 必要 的 网络连接。 解决
方法 :优化安全策略,确保 不 影响 正常 业务;定期检查 安全策略 的 有效性,避免 过度 限制。
性能优化目标
最大化
硬件资源 利用率。 降低
系统 延迟,提高 实时性。 减少
内存 占用 和 存储 I/O。 优化
网络 性能,确保 稳定 通信。
性能优化层次
性能
硬件
优化:选择 合适 的 硬件 并 合理配置 硬件 参数。 内核
优化:裁剪 内核、调整 内核 参数、优化 调度 策略 等。 应用
优化:优化 应用 程序代码、减少 资源 占用、提高 并发 性能。 系统
调优:调整 系统 服务、优化 网络 和 I/O 性能。
性能优化的基本原则
需求
驱动:优化 工作 应 基于 实际 需求,明确 性能 瓶颈 和 优化 目标。 最小化
原则:在 满足 功能 需求 的 前提 下,尽量减少 系统资源 的 占用。 分阶段
优化:按照 从 硬件 到 软件、从 系统 到 应用 的 顺序 逐步 优化,避免 盲目 调整。 测试
与 验证:优化 后 需 通过 严格 的 测试 验证 性能 提升 效果,确保 系统 稳定性。
4.4.12.2. 性能诊断工具
注意: 本章mpstat 、pidstat、iostat、sar 命令sysstat 软件包。因此,用户
BR2_PACKAGE_SYSSTAT=y
然后,重新
top
top 命令
top 的原理
top 的top 命令
内核
接口 :调用 top使用/proc文件系统中 的 信息(如 /proc/stat、/proc/meminfo、/proc/loadavg和/proc/[pid]/stat等)来获取 系统 和 进程 的 相关 数据,如 CPU 的 统计数据、上下文 切换 次数、中断 次数 等。 数据
刷新 :top默认每隔 3 秒 刷新 一次,以便 提供 实时 的 系统资源 使用 情况。用户 可以 通过 命令行 参数 来 调整 刷新 频率。 显示
内容 :top显示的 内容 通常 包括: 系统
信息:如 系统 负载、 CPU 使用率、内存 使用、交换 空间 等。 进程
信息:包括 每个 进程 的 PID、运行 时间、 CPU 和 内存 使用率 等。
/proc/stat 和 /proc/loadavg 文件说明
/proc/stat 文件
root@buildroot:~# cat /proc/stat
cpu 62804 0 114380 58089226 5453 6389 8543 0 0 0
cpu0 4066 0 7342 7271002 241 1274 1875 0 0 0
cpu1 14258 0 32454 7237220 902 659 1076 0 0 0
cpu2 8234 0 14487 7260125 1136 785 1408 0 0 0
cpu3 5561 0 9637 7267498 1234 633 1122 0 0 0
cpu4 15888 0 25333 7242372 1002 652 1082 0 0 0
cpu5 725 0 615 7282803 546 636 406 0 0 0
cpu6 494 0 402 7284148 186 480 277 0 0 0
cpu7 13576 0 24107 7244055 202 1267 1294 0 0 0
intr 4026141 0 18137 644564 0 0 0 94726 0 0 0 0 0 0 2900948 0 0 0 0 4068 0 0 0 0 0 0 0 0 0 0 21199 0 0 42 0 133083 0 0 0 12288 123959 72875 0 0 0 8 4 157 22 0 0 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 5159099
btime 0
processes 3981
procs_running 1
procs_blocked 0
softirq 3450227 24 870373 5 151367 0 0 59 1249178 0 1179221
关键字
CPU 使用
情况 cpu:含义:表示
这 一行 统计 的 是 整个 系统 的 CPU 使用 情况(所有 CPU 核心 的 总和)。
62804:字段名:
user含义:用户
态 时间( User time)。表示 CPU 在 用户 态下 运行 的 时间(单位 为 jiffies,一个 jiffy 通常 是 1/100 秒,具体 取决于 系统 的 HZ 值)。 解释: CPU 在
用户 态下 运行 的 时间,即 运行 用户 空间 程序 所 花费 的 时间。
0:字段名:
nice含义: nice 时间( Nice time)。表示 CPU 在
用户 态下 运行 nice 优先级 较 高 的 进程 所 花费 的 时间(单位 为 jiffies)。 解释: nice 优先级
较 高 的 进程 通常 是 指 那些 被 设置 为 较 低优先级 的 用户 空间 程序。在 这个 例子 中, nice时间为 0 ,表示 没有 nice 优先级 较 高 的 进程 运行。
114380:字段名:
system含义:内核
态 时间( System time)。表示 CPU 在 内核 态下 运行 的 时间(单位 为 jiffies)。 解释: CPU 在
内核 态下 运行 的 时间,即 执行 内核 代码 所 花费 的 时间,例如 系统 调用、中断 处理 等。
58089226:字段名:
idle含义:空闲
时间( Idle time)。表示 CPU 处于 空闲 状态 的 时间(单位 为 jiffies)。 解释: CPU 没有
执行 任何 任务 的 时间。在 这个 例子 中,空闲 时间 占 比较 高,说明 系统 当前 的 负载 较 低。
5453:字段名:
iowait含义: I/O 等待时间( I/O wait time)。表示 CPU 在
等待 I/O 操作 完成 时所 花费 的 时间(单位 为 jiffies)。 解释: CPU 在
等待 磁盘 I/O 操作 完成 时 的 时间。如果 这个 值较 高,可能 表示 系统 存在 I/O 瓶颈。
6389:字段名:
irq含义:中断
时间( Interrupt time)。表示 CPU 处理 硬件 中断 所 花费 的 时间(单位 为 jiffies)。 解释: CPU 处理
硬件 中断 的 时间,例如 处理 来自 硬件 设备 的 中断 信号。
8543:字段名:
softirq含义:软
中断 时间( Softirq time)。表示 CPU 处理 软 中断 所 花费 的 时间(单位 为 jiffies)。 解释:软
中断 是 内核 在 软件 层面 模拟 的 中断,用于 处理 一些 内核 任务,例如 网络 数据包 处理、定时器 事件 等。
0:字段名:
steal含义:被“窃取”的
时间( Steal time)。在 虚拟化 环境 中,表示 CPU 时间 被 虚拟机 监视器( Hypervisor)占用 的 时间(单位 为 jiffies)。 解释:在
虚拟化 环境 中,虚拟机 可能 需要 等待 物理 CPU 资源。 steal时间表示 虚拟机 等待 物理 CPU 的 时间。在 这个 例子 中, steal时间为 0 ,说明 系统 可能 不是 虚拟化 环境,或者 虚拟机 没有 等待 CPU 资源。
0:字段名:
guest含义:运行
虚拟机 的 时间( Guest time)。表示 CPU 运行 虚拟机 所 花费 的 时间(单位 为 jiffies)。 解释:在
虚拟化 环境 中, guest时间表示 CPU 运行 虚拟机 的 时间。在 这个 例子 中, guest时间为 0 ,说明 系统 可能 不是 虚拟化 环境,或者 没有 运行 虚拟机。
0:字段名:
guest_nice含义:运行 nice 优先级
较 高 的 虚拟机 的 时间( Guest nice time)。表示 CPU 运行 nice 优先级 较 高 的 虚拟机 所 花费 的 时间(单位 为 jiffies)。 解释:在
虚拟化 环境 中, guest_nice时间表示 CPU 运行 nice 优先级 较 高 的 虚拟机 的 时间。在 这个 例子 中, guest_nice时间为 0 ,说明 系统 可能 不是 虚拟化 环境,或者 没有 运行 nice 优先级 较 高 的 虚拟机。
中断
统计 intr:中断统计 信息。 4026141:总中断 次数。 其他
数字 表示 不同 中断 类型 的 次数。
上下文
切换 ctxt:上下文切换 次数。 5159099表示系统 已经 执行 了 5159099 次 上下文 切换。
系统启动
时间 btime:系统启动时间(以 秒 为 单位)。 0表示系统启动 时间 从 1970 年 1 月 1 日 开始 计算(因为 设备 上 没有 使能 RTC 时钟,系统 每次 启动 都 是从 1970 零时 启动)。
进程
信息 processes:系统启动以来 创建 的 进程 总数。 3981表示系统启动 以来 创建 了 3981 个 进程。 procs_running:当前运行 的 进程 数。 1表示当前 有 1 个 进程 正在 运行。 procs_blocked:当前处于 不可 中断 睡眠 状态 的 进程 数。 0表示没有 进程 处于 不可 中断 睡眠 状态。
软
中断 统计 softirq:软中断 统计 信息。 3450227:总软中断 次数。 其他
数字 表示 不同 类型 的 软 中断 次数。
/proc/loadavg 文件
root@buildroot:~# cat /proc/loadavg
0.00 0.02 0.00 1/199 3976
关键字
负载
平均值 0.00: 1 分钟内 的 平均 负载。 0.02: 5 分钟内 的 平均 负载。 0.00: 15 分钟内 的 平均 负载。
进程
信息 1/199:当前运行 的 进程 数 / 总 进程 数。 1表示当前 有 1 个 进程 正在 运行, 199表示系统 中 当前 的 进程 总数。 3976:最后运行 的 进程 ID。
CPU 利用率与 Load Average 的区别
在 top 显示
CPU 利用率
CPU 时间 = user + system + nice + idle + iowait + irq + softirq
CPU 利用率 = 1 - (idle) / CPU 时间,用于
测量 当前 系统 的 CPU 负载。 CPU 用户
态 = (user + nice) / CPU 时间,用于利用率 衡量 用户程序 对 CPU 的 占用率。 CPU 内核
态 = system / CPU 时间,反映利用率 程序 对 Linux 内核 的 系统 调用 占用 的 CPU 时间。 I/O 利用率 = iowait / CPU 时间,衡量
存储介质(如 FLASH、内存)的 交互 与 等待时间。
Load Average 则
总结
CPU 利用率:反映
程序 在 运行 期间 占用 的 CPU 百分比。 CPU 负载:表示
单位 时间 内 正在 使用 和 等待 使用 CPU 的 进程 平均数。
top 的限制
尽管 top 是
显示信息
不够 :详细 top默认展示 的 内容 虽然 包含 了 大部分 关键 信息,但 某些 特定 的 资源 信息 或 深入 的 分析 可能 需要 额外 的 命令 或 参数。 例如,网络
活动、磁盘 I/O 等 信息 需要 配合 其他 命令(如 iostat、sar等)一起使用。
实时性
和 :性能 开销 尽管
top是一个 实时 工具,但 它 每次 刷新 时会 重新 计算 数据,这 可能 会 给 系统 带来 一定 的 性能 开销,尤其 是 在 进程 数目 非常 多 的 情况 下。 对于
高频 次 的 数据 刷新, top的性能 可能 会 有所 下降。
可
定制 :性 较差 top提供了 基本 的 交互式 操作 和 参数设置,但 对于 复杂 的 需求,可能 需要 进行 较为 繁琐 的 配置。 比如,某些
高级 视图、图形界面 的 呈现、颜色 配置 等,需要 在 命令行 模式 下 进行 较 多 的 手动 配置。
界面
较为 :简陋 相
较 于 一些 现代 的 监控 工具, top的界面 显得 比较 简洁,不 适合 进行 深度 的 图形化 分析。 用户
在 使用 时 需要 熟悉 多种 快捷键,以便 在 动态 界面 中 有效 切换 和 获取信息。
top周期的 :选定 CPU 的
使用率 受到 周期 的 影响,在 CPU 繁忙 时 使用 top -d1和top -d5的结果 差异 是 非常 大 的,周期 越大,越 接近 实际 平均 负载。 考虑 这样 的 一种 极端 场景,在 1s 的 时间 内,前 100ms 负载 100%,后 900ms CPU 全部 idle,以 1s 为 周期,负载 就是 10%,以 100ms 为 周期,负载 就 出现 了 100% 的 情况,基于 以上 情况 考虑,一般 建议 以 5s 作为 top的周期 ( top -d5)。需要
特别 注意 的 是, top命令适用 于 长时间 的 负载 检测,对于 一次性 负载 检查 ( top -n1),top实现中 第一次 top计算的 周期 是 200ms,以 200ms 周期 计算出来 的 CPU 使用率 非常 不准,会 对 整体 分析 产生 误导。
CPU 使用率
中 :包含 iowait 一般
理解 中 CPU 使用率 是 指 CPU 忙 占 CPU 总 时间 的 比值,处于 iowait 的 线程 实际 并 不 占用 CPU,但是 目前 几乎 所有 的 统计 工具 中,都 把 iowait 统计 到 CPU 使用率 中。
top 的参数说明
板端top 命令h 交互top 命令
Help for Interactive Commands - procps-ng 3.3.17
Window 1:Def: Cumulative mode Off. System: Delay 1.5 secs; Secure mode Off.
Z,B,E,e Global: 'Z' colors; 'B' bold; 'E'/'e' summary/task memory scale
l,t,m,I Toggle: 'l' load avg; 't' task/cpu; 'm' memory; 'I' Irix mode
0,1,2,3,4 Toggle: '0' zeros; '1/2/3' cpu/numa views; '4' cpus two abreast
f,F,X Fields: 'f'/'F' add/remove/order/sort; 'X' increase fixed-width
L,&,<,> . Locate: 'L'/'&' find/again; Move sort column: '<'/'>' left/right
R,H,J,C . Toggle: 'R' Sort; 'H' Threads; 'J' Num justify; 'C' Coordinates
c,i,S,j . Toggle: 'c' Cmd name/line; 'i' Idle; 'S' Time; 'j' Str justify
x,y . Toggle highlights: 'x' sort field; 'y' running tasks
z,b . Toggle: 'z' color/mono; 'b' bold/reverse (only if 'x' or 'y')
u,U,o,O . Filter by: 'u'/'U' effective/any user; 'o'/'O' other criteria
n,#, ^ O . Set: 'n'/'#' max tasks displayed; Show: Ctrl+'O' other filter(s)
V,v . Toggle: 'V' forest view; 'v' hide/show forest view children
k,r Manipulate tasks: 'k' kill; 'r' renice
d or s Set update interval
W,Y,! Write config file 'W'; Inspect other output 'Y'; Combine Cpus '!'
q Quit
( commands shown with '.' require a visible task display window )
Press 'h' or '?' for help with Windows,
Type 'q' or <Esc> to continue
top 命令
常用
选项 :-d <秒数>:设置刷新 间隔时间(单位 为 秒),例如 top -d 2表示每 2 秒 刷新 一次。 -n <次数>:指定top命令运行 的 次数 后 自动 退出。 -p <进程 ID>:仅显示 指定 进程 ID 的 信息。 -u <用户名>:仅显示 指定 用户名 的 进程 信息。 -b:以批处理 模式 运行,适用 于 脚本 中 调用。 -c:显示完整 的 命令行 而 不 截断。
交互式
命令 (根据 help 菜单信息 进行 说明): 全局
命令: Z:切换颜色 显示。 B:切换粗体 显示。 E/e:切换摘要 / 任务 内存 比例 显示。
切换
显示 项: l:切换显示 负载 平均值。 t:切换显示 任务 /CPU 信息。 m:切换显示 内存 信息。 I:切换Irix模式与 Solaris模式。 Irix 模式:在Irix模式下, top 会 显示 进程 的 累计 CPU 使用率,不 考虑 CPU 核心 数。如果 一个 进程 在 多 核 系统 中 使用 了 多个 核心,它 的 CPU 使用率 可能 会 超过 100%。 Solaris 模式:在 Solaris模式下, top 会 将 进程 的 CPU 使用率 除以 CPU 核心 数,从而 显示 每个 进程 的 平均 CPU 使用率。因此,一个 进程 的 CPU 使用率 最多为 100%。
CPU 视图
切换: 0:切换显示 零值。 1/2/3:切换 CPU/NUMA 视图。4:切换 CPU 两列显示。
字
段 设置: f/F:添加 / 移除 / 排序 / 排序字 段。 X:增加固定 宽度 显示。
查找
和 定位: L/&:查找 / 再次查找。 </>:左右移动 排 序列。
排序
和 显示 格式: R:切换排序。 H:切换线程 显示。 J:切换数字 对齐。 C:切换坐标 显示。
其他
切换: c:切换命令 名称 / 行 显示。 i:切换空闲 任务 显示。 S:切换时间 显示。 j:切换字符串 对齐。 x:切换排序 字 段 高亮。 y:切换运行 任务 高亮。 z:切换颜色 / 单色 显示。 b:切换粗体 / 反向 显示(仅 在 x或y时有效)。
过滤
和 用户 筛选: u/U:按有效 / 任意 用户 过滤。 o/O:按其他 标准 过滤。
显示
设置: n/#:设置显示 的 最大 任务 数。 Ctrl+O:显示其他 过滤 条件。 V:切换森林 视图。 v:隐藏 / 显示森林 视图 子项。
进程
管理: k:终止进程(需要 输入 PID)。 r:更改进程 优先级(需要 输入 PID 和 新 的 nice 值)。
更新
时间 间隔 设置: d或s:更改刷新 间隔时间。
配置
和 退出: W:写入配置文件。 Y:检查其他 输出。 !:合并 CPU。q:退出top。
字
段 :管理器 f:进入字 段 管理器,允许 选择 显示 哪些 列。 o:设置当前 排序 规则。
top 的使用说明
基本
语法 :top [ 选项 ]
以下top 命令
top - 19:24:50 up 19:24, 2 users, load average: 0.02, 0.02, 0.00
Tasks: 180 total, 1 running, 178 sleeping, 1 stopped, 0 zombie
%Cpu0 : 0.0/0.0 0[ ]
%Cpu1 : 0.0/0.0 0[ ]
%Cpu2 : 1.3/1.3 3[|| ]
%Cpu3 : 0.0/0.0 0[ ]
%Cpu4 : 1.9/0.6 3[| ]
%Cpu5 : 0.0/0.6 1[ ]
%Cpu6 : 0.0/0.0 0[ ]
%Cpu7 : 0.0/0.6 1[ ]
GiB Mem : 67.5/1.3 [ ]
GiB Swap: 0.0/0.0 [ ]
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 2.1m 0.1m 0.0 0.0 0:02.29 S init [3]
237 root 20 0 5.8m 2.0m 0.0 0.2 0:00.23 S `- /sbin/udevd -d
404 dbus 20 0 3.3m 0.2m 0.0 0.0 0:00.00 S `- dbus-daemon --system
408 root 20 0 2.1m 0.1m 0.0 0.0 0:00.00 S `- /usr/sbin/tee-supplicant -d /dev/teepriv0
413 root 20 0 4.5m 0.2m 0.0 0.0 0:00.00 S `- /usr/libexec/bluetooth/bluetoothd -n
436 root 20 0 71.4m 0.6m 0.0 0.0 0:14.56 S `- /usr/sbin/ntpd -g -p /var/run/ntpd.pid
441 root 20 0 6.3m 1.9m 0.0 0.1 0:00.00 S `- sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
...
输出
系统
状态 信息 top - 19:24:50 up 19:24, 2 users, load average: 0.02, 0.02, 0.00当前
时间: 19:24:50 系统
运行 时间: 19 小时 24 分钟 当前
登录 用户数: 2 系统
负载 平均值: 0.02 ( 1 分钟)、 0.02 ( 5 分钟)、 0.00 ( 15 分钟)
任务
状态 Tasks: 180 total, 1 running, 178 sleeping, 1 stopped, 0 zombie总
进程 数: 180 运行
中 进程 数: 1 睡眠
中 进程 数: 178 停止
的 进程 数: 1 僵尸
进程 数: 0
CPU 使用
情况 %Cpu0 : 0.0/0.0 0[ ]CPU0 的
使用率 为 0.0%
%Cpu2 : 1.3/1.3 3[|| ]CPU2 的
使用率 为 1.3%
%Cpu4 : 1.9/0.6 3[| ]CPU4 的
使用率 为 1.9%
内存
使用 情况 GiB Mem : 67.5/1.3 [ ]总
内存: 67.5 GiB 已
使用 内存: 1.3 GiB
交换
空间 使用 情况 GiB Swap: 0.0/0.0 [ ]总
交换 空间: 0.0 GiB 已
使用 交换 空间: 0.0 GiB
进程
列表 PID:进程 IDUSER:进程所有者 PR:进程优先级 NI:进程的 nice 值 VIRT:进程占用 的 虚拟内存 RES:进程占用 的 物理 内存 %CPU:进程占用 的 CPU 百分比 %MEM:进程占用 的 物理 内存 百分比 TIME+:进程累计 运行 时间 S:进程状态( S 表示 睡眠, R 表示 运行) COMMAND:进程启动 的 命令
htop 简介
当前htop 命令,htop 是 top 命令top 相比,htop 支持htop 具有
CPU 使用率
和 进程 使用率 均 采用 Solaris 模式(在 Solaris模式下, top 会 将 进程 的 CPU 使用率 除以 CPU 核心 数,从而 显示 每个 进程 的 平均 CPU 使用率。因此,一个 进程 的 CPU 使用率 最多为 100%)。 支持
在线 对 进程 的 设置 Nice、 CPU 亲和性 进行 修改。
root@buildroot:~# htop -h
htop 3.2.1
(C) 2004-2019 Hisham Muhammad. (C) 2020-2022 htop dev team.
Released under the GNU GPLv2+.
-C --no-color Use a monochrome color scheme
-d --delay=DELAY Set the delay between updates, in tenths of seconds
-F --filter=FILTER Show only the commands matching the given filter
-h --help Print this help screen
-H --highlight-changes[=DELAY] Highlight new and old processes
-M --no-mouse Disable the mouse
-p --pid=PID[,PID,PID...] Show only the given PIDs
--readonly Disable all system and process changing features
-s --sort-key=COLUMN Sort by COLUMN in list view (try --sort-key=help for a list)
-t --tree Show the tree view (can be combined with -s)
-u --user[=USERNAME] Show only processes for a given user (or $USER)
-U --no-unicode Do not use unicode but plain ASCII
-V --version Print version info
Long options may be passed with a single dash.
Press F1 inside htop for online help.
See 'man htop' for more information.
启动htop 会以htop 启动F1 显示
htop 3.2.1 - (C) 2004-2019 Hisham Muhammad. (C) 2020-2022 htop dev team.
Released under the GNU GPLv2+. See 'man' page for more info.
CPU usage bar: [low/normal/kernel/guest used%]
Memory bar: [used/buffers/shared/cache used/total]
Swap bar: [used/cache used/total]
Type and layout of header meters are configurable in the setup screen.
In monochrome, meters display as different chars, in order: |#*@$%&.
Process state: R: running; S: sleeping; t: traced/stopped; Z: zombie; D: disk sleep
Tab: switch to next screen tab S-Tab: switch to previous screen tab
Arrows: scroll process list Space: tag process
Digits: incremental PID search c: tag process and its children
F3 /: incremental name search U: untag all processes
F4 \: incremental name filtering F9 k: kill process/tagged processes
F5 t: tree view F7 ]: higher priority (root only)
p: toggle program path F8 [: lower priority (+ nice)
m: toggle merged command e: show process environment
Z: pause/resume process updates i: set IO priority
u: show processes of a single user l: list open files with lsof
H: hide/show user process threads x: list file locks of process
K: hide/show kernel threads s: trace syscalls with strace
F: cursor follows process w: wrap process command in multiple lines
+ - *: expand/collapse tree/toggle all F2 C S: setup
N P M T: sort by PID, CPU%, MEM% or TIME F1 h ?: show this help screen
I: invert sort order F10 q: quit
F6 > .: select sort column
Press any key to return.
以下
状态栏
CPU usage bar:显示
不同 CPU 状态 的 使用率,包括 用户 态( low)、 nice 用户 态( normal)、系统 态( kernel)、客户机 虚拟 CPU( guest)。 Memory bar:显示
物理 内存 的 使用 情况,包括 已 用 内存、缓冲区、共享内存、缓存。 Swap bar:显示
交换 分区 的 使用 情况,包括 已 用 交换 空间、缓存。
界面
Tab:切换
到 下 一个 屏幕 标签 页。 S-Tab:切换
到 上 一个 屏幕 标签 页。 Arrows:滚动
进程 列表。 Space:标记
进程。 Digits:按 PID 增量
搜索 进程。 c:标记
进程 及其 子 进程。 F3 /:按
名称 增量 搜索 进程。 U:取消
标记 所有 进程。 F4 \:按
名称 过滤 进程。 F9 k:杀死
被 标记 的 进程。 F5 t:以
树状 视图 显示 进程。 F7 ]:提高
被 标记 进程 的 优先级(需要 root 权限)。 F8 [: 降低
被 标记 进程 的 优先级(增加 nice 值)。 p:切换
显示 程序 路径。 m:切换
合并 命令 的 显示。 e:显示
进程 的 环境变量。 Z:暂停 / 恢复
进程 更新。 i:设置
进程 的 IO 优先级。 u:显示
单个 用户 的 进程。 l:使用
lsof列出进程 打开 的 文件。 H:隐藏 / 显示
用户 进程 的 线程。 x:列出
进程 的 文件 锁。 K:隐藏 / 显示
内核 线程。 s:使用
strace跟踪系统 调用。 F:光标跟随
选中 的 进程。 w:将
进程 命令 换行 显示。 + - *:展开 / 折叠
树状 视图 或 切换 所有。 F2 C S:进入
设置 屏幕。 N P M T:按 PID、 CPU%、 MEM% 或 TIME 排序。
F1 h ?:显示
帮助 屏幕。 I:反转
排序 顺序。 F10 q:退出
htop。F6 > .:选择
排 序列。
进程
R:运行
中。 S:休眠。
t:被
跟踪 / 停止。 Z:僵尸
进程。 D:等待 I/O。
其他:
标题栏
中 显示 的 类型 和 布局 可以 在 设置 屏幕 中 配置。 在
单色 模式 下,仪表 显示 为 不同 的 字符,顺序 为: |#*@$%&。
mpstat
mpstat(Multiprocessor Statistics) 是sysstat 包mpstat 可以
mpstat 的原理
mpstat 通过/proc/stat 文件/proc/stat 是mpstat 通过
mpstat 的参数说明
mpstat 命令行
-A或--all:显示所有 CPU 的 统计 信息。 -n或--repeat:与<interval>和<count>一起使用,重复 执行 mpstat命令。-T或--threads:显示线程 的 CPU 使用率。 -u或--sum:只显示 CPU 总和 的 统计 信息。 -V或--version:显示mpstat的版本信息。 -I {SUM|CPU|SCPU|ALL}:选择显示 的 CPU 指标 类型。 SUM:所有 CPU 指标的 总和。 CPU:每个 CPU 的指标。 SCPU:每个 CPU 的指标,不 包括 空闲 CPU。 ALL:所有 CPU 指标和 每个 CPU 的 指标。
-N {<node_list>|ALL}:指定要 监控 的 NUMA 节点。 --dec={ 0 | 1 | 2 }:设置固定 小数点 显示 的 位数。 -o JSON:以 JSON 格式输出。 -P {<cpu_list>|ALL}:指定要 监控 的 CPU 列表。
mpstat 的使用说明
mpstat 的
格式:
mpstat [options] [ <interval> [ <count> ] ]
选项 时间间隔 采集次数
基本
用户mpstat 命令
mpstat
这%usr)、系统%sys)、 I/O 等待(%iowait)等。
重复
用户-n 参数mpstat 命令,以便
mpstat -n 1 5
显示
如果-P 参数
mpstat -P 0,1
这
指定
用户-o 参数
mpstat -o JSON
mpstat 示例
以下mpstat 命令
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
05:05:39 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
05:05:39 all 0.10 0.00 0.21 0.02 0.01 0.01 0.00 0.00 0.00 99.65
字
%usr:用户空间 占用 的 CPU 时间 百分比( 0.10%)。 %nice:调整过 优先级 的 进程 占用 的 CPU 时间 百分比( 0.00%)。 %sys:系统空间 占用 的 CPU 时间 百分比( 0.21%)。 %iowait:等待 I/O 操作完成 的 时间 百分比( 0.02%)。 %irq:处理硬件 中断 的 时间 百分比( 0.01%)。 %soft:处理软件中断 的 时间 百分比( 0.01%)。 %steal:虚拟机被 其他 虚拟机 占用 的 时间 百分比( 0.00%)。 %guest:运行客户机 虚拟 CPU 的 时间 百分比( 0.00%)。 %gnice:调整过 优先级 的 客户机 进程 占用 的 CPU 时间 百分比( 0.00%)。 %idle: CPU 空闲时间 百分比( 99.65%)。
pidstat
pidstat 是 sysstat 工具
pidstat 的原理
pidstat 也/proc 文件系统/proc 是 Linux 内核pidstat 分析
pidstat 的参数说明
pidstat 支持
-u:显示各个 进程 的 CPU 使用 统计 信息。 -r:显示各个 进程 的 内存 使用 情况。 -d:显示各个 进程 的 I/O 使用 情况。 -w:显示各个 进程 的 上下文 切换 情况。 -t:显示线程 信息。 -p <pid>:指定进程 号,仅 显示 指定 进程 的 统计 信息。 -l:显示命令 名 和 所有 参数。 -C <command>:仅显示 命令 中 包含 匹配 字符串 的 进程。 -G <process_name>:显示符合 匹配 进程 名字 的 进程。 -T { TASK | CHILD | ALL }:显示任务 的 线程 或子 进程 信息。 --dec={ 0 | 1 | 2 }:设置固定 小数点 显示 的 位数。 --human:以易读 的 格式 显示 数值。
pidstat 的使用说明
pidstat 的
格式:
pidstat [options] [ <interval> [ <count> ] ]
选项 时间间隔 采集次数
pidstat 示例
pidstat以下
是 pidstat命令的 示例 输出: root@buildroot:~# pidstat Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU) 05:29:56 UID PID %usr %system %guest %wait %CPU CPU Command 05:29:56 0 1 0.00 0.01 0.00 0.00 0.01 1 init [3] 05:29:56 0 2 0.00 0.00 0.00 0.00 0.00 1 kthreadd 05:29:56 0 9 0.00 0.00 0.00 0.00 0.00 3 kworker/u16:0+dsp_dump_wq 05:29:56 0 11 0.00 0.00 0.00 0.00 0.00 0 ksoftirqd/0 05:29:56 0 12 0.01 0.00 0.00 0.00 0.01 6 rcu_preempt ...
UID:进程所有者 的 用户名。 PID:进程 ID。%usr:用户空间 占用 的 CPU 时间 百分比。 %system:系统空间 占用 的 CPU 时间 百分比。 %guest:运行客户机 虚拟 CPU 的 时间 百分比。 %wait:等待 I/O 操作完成 的 时间 百分比。 %CPU:进程占用 的 总 CPU 时间 百分比。 CPU:进程运行 所在 的 CPU。 Command:进程的 命令 名称。
注:运行 pidstat 不
加 任何 选项,统计 的 信息 为 系统启动 开始 的 各项 统计 信息 使用-r 选项
统计 进程 内存 使用 情况 root@buildroot:~# pidstat -r 20 1 Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU) 05:50:21 UID PID minflt/s majflt/s VSZ RSS %MEM Command 05:50:41 0 2042 0.05 0.00 3828 2724 0.20 pidstat Average: UID PID minflt/s majflt/s VSZ RSS %MEM Command Average: 0 2042 0.05 0.00 3828 2724 0.20 pidstat
minflt/s:从
内存 中 加载 数据 时 每秒 出现 的 次要 错误 的 数目,这些 不 要求 从 磁盘 载入 内存 页面 majflt/s:从
内存 中 加载 数据 时 每秒 出现 的 主要 错误 的 数目,这些 要求 从 磁盘 载入 内存 页面,一般 在 内存 使用 紧张 时 产生。 VSZ:占用
的 虚拟内存 大小,包括 进入 交换 分区 的 内存 RSS:占用
的 物理 内存大小,不 包括 进入 交换 分区 的 内存 %MEM:进程
使用 的 物理 内存 百分比
使用-d 选项
统计 进程 IO 使用 情况 root@buildroot:~# pidstat -d 20 1 Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU) 05:57:00 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command 05:57:20 0 799 0.00 0.20 0.00 0 syslogd Average: UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command Average: 0 799 0.00 0.20 0.00 0 syslogd
kB_rd/s:进程
每秒 从 磁盘 读取 的 数据量 ( 以 kB 为 单位 ) kB_wr/s:进程
每秒 向 磁盘 写入 的 数据量 ( 以 kB 为 单位 ) kB_ccwr/s:任务
写入 磁盘 被 取消 的 速率 ( 以 kB 为 单位 ) iodelay:任务
的 I/O 阻塞 延迟,以 时钟 周期 为 单位,包括 等待 同步 块 I/O 和 换入 块 I/O 结束 的 时间
使用-w 选项
显示 进程 的 上下文 切换 情况 root@buildroot:~# pidstat -w 20 1 Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU) 06:00:04 UID PID cswch/s nvcswch/s Command 06:00:24 0 1 0.20 0.00 init 06:00:24 0 2 0.05 0.00 kthreadd 06:00:24 0 11 0.05 0.00 ksoftirqd/0 06:00:24 0 12 5.34 0.00 rcu_preempt 06:00:24 0 13 1.00 0.00 migration/0 06:00:24 0 17 1.00 0.00 migration/1 ... Average: UID PID cswch/s nvcswch/s Command Average: 0 1 0.20 0.00 init Average: 0 2 0.05 0.00 kthreadd Average: 0 11 0.05 0.00 ksoftirqd/0 Average: 0 12 5.34 0.00 rcu_preempt Average: 0 13 1.00 0.00 migration/0 Average: 0 17 1.00 0.00 migration/1 ...
cswch/s :表示
每秒 自愿 上下文 切换 的 次数 nvcswch/s :表示
每秒 非 自愿 上下文 切换 的 次数
注:所谓
自愿 上下文 切换,是 指 进程 无法 获得 所 需 的 资源 导致 的 上下文 切换。而 非 自愿 上下文 切换,则 是 指 进程 由于 cpu 分配 的 时间 片 耗尽,被 系统 强制 调度 导致 的 上下文 切换
iostat
iostat 命令sysstat 软件包
iostat 的参数说明
-c:显示 CPU 使用情况。该 选项 会 输出 CPU 的 利用率、用户 态 时间、系统 态 时间、空闲 时间 等 信息,帮助 用户 了解 CPU 的 负载 情况。 -d:显示磁盘 使用 情况。该 选项 会 输出 磁盘 的 读写 次数、读写 速率、平均 队列 长度、平均 等待时间 等 信息,帮助 用户 了解 磁盘 的 IO 性能。 --dec={0|1|2}:指定要 使用 的 小数位 数,默认 为 2 位 小数。例如, --dec=1表示输出 结果 保留 1 位 小数。 -g GROUP_NAME {DEVICE [...] | ALL}:显示一组 设备 的 统计 信息。 GROUP_NAME为设备组 的 名称, DEVICE为组内 的 设备 名称, ALL表示显示 组内 所有 设备 的 统计 信息。 -H:此选项 必须 与 -g选项一起 使用,指示 只 显示 组 的 全局 统计 信息,而 不 显示 组中 单个 设备 的 统计 信息。 -h:以可读格式 打印 大小,例如 将 字节 单位 转换 为 更 易读 的 KB、 MB 等 单位。 -j {ID | LABEL | PATH | UUID | ...} [DEVICE [...] | ALL]:指定设备 的 标识 方式,可以 是 设备 ID、标签、路径、 UUID 等。 DEVICE为具体 的 设备 名称, ALL表示所有 设备。
iostat 的使用说明
iostat 的
格式:
iostat [options] [ <device name> <interval> [ <count> ] ]
选项 设备名称 时间间隔 采集次数
CPU 使用
情况 :当使用 -c选项时,输出 内容 包括 %user(用户态 时间 占 比)、 %nice(低优先级用户 态 时间 占 比)、 %system(系统态 时间 占 比)、 %iowait( IO 等待时间占 比)、 %steal(虚拟化环境 下 的 时间 占 比)、 %idle(空闲时间 占 比)等 指标。其中, %iowait指标较 高时,可能 表示 系统 存在 磁盘 IO 瓶颈。 磁盘
使用 :当情况 使用 -d选项时,输出 内容 包括 rrqm/s(每秒读取 的 合并 请求 次数)、 wrqm/s(每秒写入 的 合并 请求 次数)、 r/s(每秒读取 次数)、 w/s(每秒写入 次数)、 rkB/s(每秒读取 的 KB 数)、 wkB/s(每秒写入 的 KB 数)、 await(平均等待时间)、 svctm(平均服务 时间)、 %util(磁盘利用率)等 指标。其中, %util指标接近 100% 时,可能 表示 磁盘 处于 饱和状态,存在 IO 瓶颈。
通过iostat 命令
%iowait: CPU 等待 IO 操作的 时间 占 比。如果 该值 较 高(例如 超过 20%),可能 表示 磁盘 IO 性能 不足,导致 CPU 等待时间 过长。 %util:磁盘利用率。如果 该值 接近 100%,表示 磁盘 处于 饱和状态,无法 及时处理 更 多 的 IO 请求。 await:平均等待时间。如果 该值 较 高,可能 表示 磁盘 响应速度 较慢,存在 IO 瓶颈。 svctm:平均服务 时间。如果 该值 较 高,也 可能 表示 磁盘 性能 较差,需要 进一步 分析。
iostat 示例
以下iostat 命令
root@buildroot:~# iostat -cd 1 5
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.10 0.00 0.23 0.02 0.00 99.65
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
mmcblk0 0.54 4.71 47.18 0.00 106609 1067948 0
mmcblk0boot0 0.00 0.01 0.00 0.00 116 0 0
mmcblk0boot1 0.00 0.01 0.00 0.00 116 0 0
...
该
首先
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
Linux 6.1.83-DR-PL5.1_V1.0.16 是buildroot 则01/01/70 当前_aarch64_ 是 CPU 的(8 CPU) 显示
第二
avg-cpu: %user %nice %system %iowait %steal %idle
0.10 0.00 0.23 0.02 0.00 99.65
cpu 属性
%user: CPU 处在用户 模式 下 的 时间 百分比。 %nice: CPU 处在带 NICE 值 的 用户 模式 下 的 时间 百分比。 %system: CPU 处在系统 模式 下 的 时间 百分比。 %iowait: CPU 等待输入输出 完成 时间 的 百分比。 %steal:管理程序维护 另 一个 虚拟 处理器 时,虚拟 CPU 的 无意识 等待时间 百分比。 %idle: CPU 空闲时间 百分比。
第三
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
mmcblk0 0.54 4.71 47.18 0.00 106609 1067948 0
mmcblk0boot0 0.00 0.01 0.00 0.00 116 0 0
mmcblk0boot1 0.00 0.01 0.00 0.00 116 0 0
每
Device:/dev 目录
下 的 磁盘(或 分区)名称。 tps:该
设备 每秒 的 传输 次数。一次 传输 对应 一次 I/O 请求,多个 逻辑 请求 可能 会 合并 为 一次 I/O 请求。每次 传输 的 大小 无法 确定。 kB_read/s:每秒
从 磁盘 读取 的 数据量,单位 为 KB/s。 kB_wrtn/s:每秒
写入 磁盘 的 数据量,单位 为 KB/s。 kB_dscd/s:每秒
磁盘 丢失 的 数据 块数,单位 为 KB/s。 kB_read:从
磁盘 读取 的 总 数据量,单位 为 KB。 kB_wrtn:写入
磁盘 的 总 数据量,单位 为 KB。 kB_dscd:磁盘
丢失 的 总 数据 块数。
需要iostat -dk 2 的kB_wrtn 表示kB_read 表示kB_dscd 表示
如果iostat -dk,则 kB_wrtn 表示kB_read 表示kB_dscd 表示
除此以外,iostat 可以-x 输出
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
mmcblk0 0.12 4.46 0.02 17.18 3.81 38.27 0.41 44.77 0.16 27.78 77.38 108.10 0.00 0.00 0.00 0.00 0.00 0.00 0.14 0.92 0.03 0.25
mmcblk0boot0 0.00 0.00 0.00 0.00 6.55 4.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
mmcblk0boot1 0.00 0.00 0.00 0.00 6.48 4.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
对
读
r/s:每秒
向 磁盘 发起 的 读 操作 次数。 rkB/s:每秒
读取 的 数据量,单位 为 KB/s。 rrqm/s:每秒
合并 的 读取 请求 数。当 系统 调用 读取数据 时, VFS 将 请求 发送到 文件系统,如果 文件系统 发现 多个 读取 请求 指向 相同 的 磁盘 块,它会 将 这些 请求 合并 为 一个 请求。 %rrqm:合并
读 请求 占 总 读取 请求 的 百分比。 r_await:每个
读 操作 的 平均 响应 时间,包含 硬盘 设备 的 读取 时间 和 在 内核 队列 中 的 等待时间。 rareq-sz:平均
读 请求 大小。
写
w/s:每秒
向 磁盘 发起 的 写 操作 次数。 wkB/s:每秒
写入 的 数据量,单位 为 KB/s。 wrqm/s:每秒
合并 的 写 请求 数。 %wrqm:合并
写 请求 占 总写 请求 的 百分比。 w_await:每个
写 操作 的 平均 响应 时间,包含 硬盘 设备 的 写入 时间 和 在 内核 队列 中 的 等待时间。 wareq-sz:平均
写 请求 大小。
抛弃
d/s:每秒
设备 完成 的 抛弃 请求 数(合并 后 的 请求)。 dkB/s:每秒
从 设备 中 抛弃 的 数据量,单位 为 KB/s。 drqm/s:每秒
排队 到 设备 中 的 合并 抛弃 请求 数量。 %drqm:抛弃
请求 在 发送到 设备 之前 已 合并 的 百分比。 d_await:发出
抛弃 请求 后 设备 服务 请求 的 平均 等待时间(以 毫秒 为 单位)。此 指标 包括 请求 在 队列 中 等待 的 时间 以及 设备 处理 请求 的 时间。 dareq-sz:发送给
设备 的 抛弃 请求 的 平均 大小(单位 为 KB)。
其他
aqu-sz:平均
请求 队列 长度。 %util:设备
在 一秒 内 用于 I/O 操作 的 时间 百分比,即 I/O 消耗 的 CPU 时间 比例。该值 反映 了 设备 的 带宽 利用率。当 串行 服务 请求 的 设备 的 此值 接近 100% 时,通常 表示 设备 已经 饱和。对于 支持 并行 请求 的 设备(如 RAID 阵列 或 现代 SSD),此值 并 不 完全 反映 性能 瓶颈。虽然 较 高 的 %util 值 表明 I/O 接近 瓶颈,但 较 低 的 值 并 不 意味着 I/O 没有 瓶颈。通常,当 %util 超过 70% 时, I/O 压力 较大。可以 结合 vmstat的 b(等待资源 的 进程 数)和 wa( I/O 等待 所 占 的 CPU 时间 百分比,超过 30% 时 表示 I/O 压力 大)参数 进一步 分析。
iowait 指标解释及常见误解
iowait 计算方法:
%iowait 是 %idle 的
如果 CPU 处于
空闲 状态( idle),内核会 检查: 是否
有 本地 磁盘 I/O 请求 未 完成。 是否
有 网络 磁盘 挂载 操作。
如果
满足 任一 条件, iowait计数器加 1 ;若 都 不 满足,则 idle计数器加 1 。
计算公式 :
iowait = (CPU 空闲时,等待 I/O 的时间 ) / (CPU 空闲的总时间 )
这个
当 CPU 处于
空闲 状态( idle),操作系统 检查 是否 有 I/O 请求 未 完成。如果 有 I/O 请求,系统 会 标记 为 iowait。 如果
在 CPU 空闲 时,存在 I/O 请求 正在 等待 完成,那么 这 段时间 被 计算 为 iowait。 如果
没有 I/O 请求, CPU 空闲 时间 被 计算 为 idle。
例如,假设
sys计数为 2 user计数为 3 nice计数为 0 iowait计数为 1 steal计数为 0 idle计数为 94
这些
sys: 2%user: 3%nice: 0%iowait: 1%steal: 0%idle: 94%
iowait 的
误解1:iowait 表示 CPU 等待 I/O 完成,在此期间
无法 处理 其他 任务
实际上,iowait的前提 是 CPU 处于 空闲 状态,并且 有 未 完成 的 I/O 请求。虽然 iowait表示 CPU 空闲,但这 并 不 意味着 CPU 不能 接收 其他 任务。 CPU 空闲 时,可能 是因为 没有 可 运行 的 任务,或者 它 正在 等待 事件(例如 磁盘 I/O、键盘输入 或 网络 数据)。 误解2:iowait 高
表示 系统 I/O 瓶颈 iowait高并 不 意味着 等待 I/O 的 进程 数量 增加 或 它们 的 等待时间 延长(进程 由于 等待 I/O 而 休眠 时间 增加)。 iowait反映的 是 CPU 处于 空闲 状态 且 有 I/O 请求 未 完成,但 不 直接 意味着 更 多 进程 正在 等待 I/O。
iowait 并iowait 增高
可以

从iowait 的%iowait 不能
vmstat
vmstat( Virtual Memory Statistics)是vmstat 收集vmstat 通过vmstat 的
vmstat 的原理
vmstat 在/proc 文件系统(尤其/proc/stat 和 /proc/meminfo)访问
它会
周期性地 从 操作系统 内核 中 获取 统计 信息。 这些
信息 是 基于 操作系统 内核 调度、内存 管理、 I/O 调度 等 模块 动态 计算 得出 的。 vmstat定期查询 这些 统计 信息,并 将 其以 易读 的 格式 展示 给 用户。
数据
内存
统计 :
内存的 统计数据 由 内核 管理, vmstat主要关注 的 是 物理 内存 的 使用 情况,包括: free:空闲
内存 buff:用于
缓冲 的 内存 cache:用于
文件 缓存 的 内存 swap:交换
分区 的 使用 情况
这些
数据 反映 了 内存 的 分配、释放、以及 缓存 与 交换 空间 的 使用 情况。 进程
与 CPU 统计 :procs(进程
状态):这部分 显示 了 进程 在 系统 中 的 状态,比如: r:就绪队列 中 的 进程 数 b:等待 I/O 的进程 数 w:进程睡眠 等待 I/O 的 数目
CPU 统计:包括 CPU 的
使用 情况: us( user): 用户态 时间 sy( system): 系统态 时间 id( idle): 空闲时间 wa( wait): 等待 I/O 的时间 st( steal):虚拟化环境 下,当前 CPU 时间 被 其他 虚拟机 偷取 的 时间
I/O 统计:
bi( blocks in):每秒
从块 设备 读入 的 块 数 bo( blocks out):每秒
写入 到 块 设备 的 块 数 in( interrupts):每秒
的 硬 中断 数量 cs( context switches):每秒
的 上下文 切换 次数
交换
空间 :si( swap in):每秒
从 交换 空间 读取 的 数据量 so( swap out):每秒
写入 到 交换 空间 的 数据量
vmstat 的参数说明
vmstat 命令
-a显示活跃 和 非 活跃 内存 的 统计 信息。 -f显示从 系统启动 至今 的 fork数量。-m显示slabinfo,即内核 slab 分配器 的 详细信息。 -n只在 开始 时 显示 一次 各 字段名。 -S unit指定输出 的 单位,可选值 为 k(千字节)、 m(兆字节)。 -d显示磁盘 I/O 统计 信息。 -p disk partition显示指定 磁盘分区 的 统计 信息。 -V显示vmstat版本信息。delay指定采样 间隔时间(秒),用于 周期性 输出 统计 信息。 count指定输出 的 采样 次数。
vmstat 的使用说明
vmstat 的
格式:
vmstat [options] [ <delay> [ <count> ] ]
选项 时间间隔 采集次数
基本
查看
系统 :运行整体 状态 vmstat命令,不带任何 参数,将 输出 系统 当前 的 虚拟内存、进程、 CPU 等 统计 信息。 vmstat
周期性
监控 :通过指定 delay和count参数,可以周期性地 输出 系统 状态 信息。例如,每 2 秒 输出 一次,共 输出 5 次。 vmstat 2 5
高级
显示
活跃 :使用和 非 活跃 内存 -a参数,可以查看 活跃 和 非 活跃 内存 的 统计 信息。 vmstat -a显示
磁盘 I/O 统计 :使用信息 -d参数,可以查看 磁盘 I/O 操作 的 详细 统计。 vmstat -d指定
磁盘分区 :通过统计 -p参数,可以指定 查看 某个 磁盘分区 的 统计 信息。 vmstat -p /dev/sda1
显示
内核 slab 分配器 :使用信息 -m参数,可以查看 内核 slab 分配器 的 详细信息。 vmstat -m注意: 在 X5 BSP 配置
中,SLAB 默认 不 开启,所以 此项 命令 不可 用。 显示
系统启动 :使用至今 的 fork 数量 -f参数,可以查看 系统启动 至今 的 fork数量。vmstat -f
vmstat 示例
root@buildroot:~# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 399916 27532 701884 0 0 1 5 7 9 0 0 100 0 0
vmstat 命令
procs:进程
相关 统计 信息。 r:运行队列 中 的 进程 数。 b:处于不可 中断 睡眠 状态 的 进程 数。
memory:内存
相关 统计 信息。 swpd:已使用 的 虚拟内存(交换 空间)。 free:空闲内存。 buff:用作缓冲区 的 内存 量。 cache:用作页面 缓存 的 内存 量。
swap:交换
空间 相关 统计 信息。 si:从交换 空间 读入 内存 的 速率。 so:写入交换 空间 的 速率。
io: I/O 操作
相关 统计 信息。 bi:块设备 读入 速率。 bo:块设备 写入 速率。
system:系统
相关 统计 信息。 in:每秒中断 数。 cs:每秒上下文 切换 次数。
cpu: CPU 相关
统计 信息。 us:用户态 CPU 时间。 sy:系统态 CPU 时间。 id: CPU 空闲时间。 wa: CPU 等待 I/O 操作的 时间。
free
free 是free 的
free 的原理
free 命令
/proc/meminfo:
这是 最 常见 的 文件, free命令读取 的 内存 使用 情况 数据 来自 该 文件。 /proc/meminfo包含了 系统 内存 的 详细 统计 信息,包括 总 内存、已 用 内存、空闲 内存、缓存、交换 空间 等 信息。用户 可以 通过 命令 cat /proc/meminfo查看这些 信息。 /proc/swaps:
这个文件 列出 了 系统 的 交换 空间( swap)信息,包括 每个 交换 设备 或 文件 的 使用 情况。它 显示 了 交换 分区 的 总量、已 使用量、空闲 量 等, free命令也 会 从 这个 文件 中 读取 交换 空间 的 相关 数据。
读取
root@buildroot:~# cat /proc/meminfo
MemTotal: 1338740 kB
MemFree: 363632 kB
MemAvailable: 436000 kB
Buffers: 60960 kB
Cached: 688044 kB
SwapCached: 0 kB
Active: 68644 kB
Inactive: 691292 kB
Active(anon): 124 kB
Inactive(anon): 680432 kB
Active(file): 68520 kB
Inactive(file): 10860 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 8 kB
Writeback: 0 kB
AnonPages: 11056 kB
Mapped: 5876 kB
Shmem: 669568 kB
KReclaimable: 15708 kB
Slab: 62424 kB
SReclaimable: 15708 kB
SUnreclaim: 46716 kB
KernelStack: 3264 kB
PageTables: 1060 kB
SecPageTables: 0 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 669368 kB
Committed_AS: 828236 kB
VmallocTotal: 133143592960 kB
VmallocUsed: 30364 kB
VmallocChunk: 0 kB
Percpu: 864 kB
HardwareCorrupted: 0 kB
CmaTotal: 391168 kB
CmaFree: 287688 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
root@buildroot:~# cat /proc/swaps
Filename Type Size Used Priority
分别/proc/meminfo 和 /proc/swaps 中
/proc/meminfo 文件
| 字 |
值 | 说明 |
|---|---|---|
| MemTotal | 1,338,740 kB | 系统 |
| MemFree | 363,632 kB | 空闲 |
| MemAvailable | 436,000 kB | 可用内存(包括 |
| Buffers | 60,960 kB | 文件系统 |
| Cached | 688,044 kB | 文件系统 |
| SwapCached | 0 kB | 交换 |
| Active | 68,644 kB | 活跃 |
| Inactive | 691,292 kB | 非 |
| Active(anon) | 124 kB | 活跃 |
| Inactive(anon) | 680,432 kB | 非 |
| Active(file) | 68,520 kB | 活跃 |
| Inactive(file) | 10,860 kB | 非 |
| Unevictable | 0 kB | 不能 |
| Mlocked | 0 kB | 被 |
| SwapTotal | 0 kB | 交换 |
| SwapFree | 0 kB | 空闲 |
| Dirty | 8 kB | 已 |
| Writeback | 0 kB | 正在 |
| AnonPages | 11,056 kB | 匿名 |
| Mapped | 5,876 kB | 映射 |
| Shmem | 669,568 kB | 共享内存 |
| KReclaimable | 15,708 kB | 可回收 |
| Slab | 62,424 kB | 内核 |
| SReclaimable | 15,708 kB | 可回收 |
| SUnreclaim | 46,716 kB | 不可 |
| KernelStack | 3,264 kB | 内核 |
| PageTables | 1,060 kB | 页表 |
| SecPageTables | 0 kB | 安全 |
| NFS_Unstable | 0 kB | NFS 不 |
| Bounce | 0 kB | 用于 bounce 缓存 |
| WritebackTmp | 0 kB | 写回 |
| CommitLimit | 669,368 kB | 最大 |
| Committed_AS | 828,236 kB | 已 |
| VmallocTotal | 133,143,592,960 kB | 系统 |
| VmallocUsed | 30,364 kB | 已 |
| VmallocChunk | 0 kB | 可用 |
| Percpu | 864 kB | 每个 CPU 的 |
| HardwareCorrupted | 0 kB | 硬件 |
| CmaTotal | 391,168 kB | 总 |
| CmaFree | 287,688 kB | 可用 |
| HugePages_Total | 0 | 系统 |
| HugePages_Free | 0 | 可用 |
| HugePages_Rsvd | 0 | 预留 |
| HugePages_Surp | 0 | 超额分配 |
| Hugepagesize | 2,048 kB | 每个 |
| Hugetlb | 0 kB | 使用 |
/proc/swaps 文件
| 字 |
值 | 说明 |
|---|---|---|
| Filename | 无 | 系统 |
| Type | 无 | 无 |
| Size | 0 kB | 交换 |
| Used | 0 kB | 当前 |
| Priority | 无 | 无 |
日志swaps 相关
free 的参数说明
执行 free --help 命令
root@buildroot:~# free --help
Usage:
free [options]
Options:
-b, --bytes show output in bytes
--kilo show output in kilobytes
--mega show output in megabytes
--giga show output in gigabytes
--tera show output in terabytes
--peta show output in petabytes
-k, --kibi show output in kibibytes
-m, --mebi show output in mebibytes
-g, --gibi show output in gibibytes
--tebi show output in tebibytes
--pebi show output in pebibytes
-h, --human show human-readable output
--si use powers of 1000 not 1024
-l, --lohi show detailed low and high memory statistics
-t, --total show total for RAM + swap
-s N, --seconds N repeat printing every N seconds
-c N, --count N repeat printing N times, then exit
-w, --wide wide output
--help display this help and exit
-V, --version output version information and exit
For more details see free(1).
各个
-b,--bytes:以字节 为 单位 显示 内存 使用 情况。 --kilo:以千字节( KB)为 单位 显示 内存 使用 情况。 --mega:以兆字节( MB)为 单位 显示 内存 使用 情况。 --giga:以吉字节( GB)为 单位 显示 内存 使用 情况。 --tera:以太字节( TB)为 单位 显示 内存 使用 情况。 --peta:以拍 字节( PB)为 单位 显示 内存 使用 情况。
-k,--kibi:以千字节( KiB)为 单位 显示 内存 使用 情况(基于 1024 )。 -m,--mebi:以兆字节( MiB)为 单位 显示 内存 使用 情况(基于 1024 )。 -g,--gibi:以吉字节( GiB)为 单位 显示 内存 使用 情况(基于 1024 )。 --tebi:以太字节( TiB)为 单位 显示 内存 使用 情况(基于 1024 )。 --pebi:以拍 字节( PiB)为 单位 显示 内存 使用 情况(基于 1024 )。
-h,--human:以易读 的 格式 显示 内存 使用 情况(自动 选择 合适 的 单位)。 --si:使用 1000 的幂 而 不是 1024 的 幂 来 显示 单位。
-l,--lohi:显示详细 的 低 内存 和 高 内存 统计 信息。 -t,--total:显示物理 内存 和 交换 空间 的 总和。 -s N,--seconds N:每隔 N 秒重复 打印 一次 内存 使用 情况。 -c N,--count N:重复打印 N 次 内存 使用 情况,然后 退出。 -w,--wide:使用宽 输出 格式,适合 显示 更 多列 的 数据。 --help:显示帮助 信息 并 退出。
-V,--version:显示版本信息 并 退出。
free 的使用说明
基本
显示
默认 :内存 使用 情况 free
默认
情况 下, free以千字节( KB)为 单位 显示 内存 使用 情况。 以
易读 :格式 显示 内存 使用 情况 free -h使用
-h参数可以 以 易读 的 格式 显示 内存 使用 情况,自动 选择 合适 的 单位(如 MiB、 GiB)。 显示
物理 :内存 和 交换 空间 的 总和 free -t使用
-t参数可以 显示 物理 内存 和 交换 空间 的 总和。
高级
以兆
字节(MB)为 :单位 显示 内存 使用 情况 free -m以吉
字节(GB)为 :单位 显示 内存 使用 情况 free -g每隔5秒
重复 :打印 一次 内存 使用 情况,共 打印3次 free -s 5 -c 3
显示
详细 :的 低 内存 和 高 内存 统计 信息 free -l使用
宽 :输出 格式 free -w
free 示例
以
root@buildroot:~# free -h
total used free shared buff/cache available
Mem: 1.3Gi 205Mi 355Mi 653Mi 746Mi 426Mi
Swap: 0B 0B 0B
输出
Mem(物理
内存) total:系统的 总 物理 内存大小。在 这个 例子 中,总 物理 内存 为 1.3Gi(约 1.3 吉 字节)。 used:当前已 使用 的 物理 内存 量。在 这个 例子 中,已 使用 205Mi(约 205 兆 字节)。 free:当前完全 空闲 的 物理 内存 量。在 这个 例子 中,空闲 内存 为 355Mi(约 355 兆 字节)。 shared:被多个 进程 共享 的 内存大小。在 这个 例子 中,共享内存 为 653Mi(约 653 兆 字节)。 buff/cache:被用作 系统 缓冲区 和 缓存 的 内存 量。在 这个 例子 中,缓冲区 和 缓存 的 总 大小 为 746Mi(约 746 兆 字节)。 available:估算的 可 用于 启动 新 应用程序 的 内存 量,而 无需 交换 出 其他 应用程序 的 内存。在 这个 例子 中,可用内存 为 426Mi(约 426 兆 字节)。
Swap(交换
空间) total:系统的 总 交换 空间 大小。在 这个 例子 中,总 交换 空间 为 0B( 0 字节),表示 系统 没有 配置 交换 空间。 used:当前已 使用 的 交换 空间 量。在 这个 例子 中,已 使用 交换 空间 为 0B( 0 字节)。 free:当前完全 空闲 的 交换 空间 量。在 这个 例子 中,空闲 交换 空间 为 0B( 0 字节)。
uptime
uptime 命令
uptime 的原理
uptime 是/proc/uptime 和 /proc/loadavg 文件
/proc/uptime:包含
系统 运行 时间 和 空闲 时间 的 统计 信息。 示例
内容: 4846.72 19364.37
第一列(
4846.72):系统运行 时间(以 秒 为 单位)。 第二列(
19364.37):系统空闲 时间(以 秒 为 单位)。
/proc/loadavg:包含
系统 的 负载 平均值。 示例
内容: 0.05 0.03 0.00 1/199 3976
前
三列 分别 表示 1 分钟、 5 分钟 和 15 分钟 的 负载 平均值。
uptime 的参数说明
uptime 命令
-p:以更 易读 的 格式 显示 系统 运行 时间(如天、小时、分钟)。 -s:仅显示 系统启动 时间。 --help:显示帮助 信息 并 退出。 --version:显示版本信息 并 退出。
uptime 的使用说明
基本
显示
系统 :运行 时间 和 负载 平均值 uptime
高级
以
更 :易读 的 格式 显示 系统 运行 时间 uptime -p仅
显示 :系统启动 时间 uptime -s
uptime 示例
示例 1 :显示
root@buildroot:~# uptime
20:54:32 up 20:54, 2 users, load average: 0.05, 0.03, 0.00
字
时间 (
20:54:32): 当前系统 时间 为 20:54:32 。 系统
运行 (时间 up 20:54): 系统已经 运行 了 20 分钟 54 秒。说明 系统 刚刚 启动 或 重启 不久。 用户数 (
2 users): 当前有 2 个 用户 在 系统 中 登录 或 活跃。 负载
平均值 (load average: 0.05, 0.03, 0.00):第一个
数字 ( 0.05): 过去 1 分钟的 负载 平均值。负载 较 低,表示 系统 没有 过多 的 计算 任务。 第二个
数字 ( 0.03): 过去 5 分钟的 负载 平均值。显示 负载 仍然 很 低,表示 系统 在 这 段时间 内 处于 空闲 状态。 第三个
数字 ( 0.00): 过去 15 分钟的 负载 平均值。非常低,系统 几乎 处于 空闲 状态。
这个
示例 2 :以
root@buildroot:~# uptime -p
up 20 hours, 54 minutes
示例 3 :仅
root@buildroot:~# uptime -s
2024-02-10 00:00:00
sar
sar ( System Activity Reporter ) 命令sar 是
sar 的原理
sar 通过/proc 文件系统/proc/uptime、/proc/loadavg、/proc/stat 等)来sar 的
sar 的参数说明
以下sar 命令
-B:显示分页 统计 信息( Paging statistics)。 -b:显示 I/O 和传输速率 统计 信息( I/O and transfer rate statistics)。 -d:显示块 设备 统计 信息( Block devices statistics)。 -F [MOUNT]:显示文件系统 统计 信息( Filesystems statistics)。 -H:显示大 页面( Hugepages)使用 情况 统计 信息( Hugepages utilization statistics)。 -I {<int_list> | SUM | ALL}:显示中断 统计 信息( Interrupts statistics)。 -m {<keyword> [,...] | ALL}:显示电源 管理 统计 信息( Power management statistics)。 关键字
包括: CPU: CPU 瞬时时钟 频率。 FAN:风扇转速。 FREQ: CPU 平均时钟 频率。 IN:电压输入。 TEMP:设备温度。 USB:连接到 系统 的 USB 设备。
-n {<keyword> [,...] | ALL}:显示网络 统计 信息( Network statistics)。 关键字
包括: DEV:网络接口。EDEV:网络接口(错误)。NFS: NFS 客户端。NFSD: NFS 服务器。SOCK:套接字( IPv4 )。 IP: IP 流量( IPv4 )。EIP: IP 流量( IPv4 )(错误)。ICMP: ICMP 流量( IPv4 )。EICMP: ICMP 流量( IPv4 )(错误)。TCP: TCP 流量( IPv4 )。ETCP: TCP 流量( IPv4 )(错误)。UDP: UDP 流量( IPv4 )。SOCK6:套接字( IPv6 )。 IP6: IP 流量( IPv6 )。EIP6: IP 流量( IPv6 )(错误)。ICMP6: ICMP 流量( IPv6 )。EICMP6: ICMP 流量( IPv6 )(错误)。UDP6: UDP 流量( IPv6 )。FC:光纤通道 HBA。 SOFT:基于软件 的 网络 处理。
-q [ <keyword> [,...] | PSI | ALL ]:显示系统 负载 和 压力 停顿 统计 信息。 关键字
包括: LOAD:队列长度 和 负载 平均值 统计 信息。 CPU:压力停顿 CPU 统计 信息。 IO:压力停顿 I/O 统计 信息。 MEM:压力停顿 内存 统计 信息。
-r [ALL]:显示内存 使用 情况 统计 信息( Memory utilization statistics)。 -S:显示交换 空间 使用 情况 统计 信息( Swap space utilization statistics)。 -u [ALL]:显示 CPU 使用情况 统计 信息( CPU utilization statistics)。 -v:显示内核 表 统计 信息( Kernel tables statistics)。 -W:显示交换 统计 信息( Swapping statistics)。 -w:显示任务 创建 和 系统 切换 统计 信息( Task creation and system switching statistics)。 -y:显示 TTY 设备统计 信息( TTY devices statistics)。
sar 的使用说明
使用
sar [options] [-A] [-o file] [ <interval> [ <count> ] ]
其中:
interval:为采样 间隔; count:为采样 次数,默认值 是 1 ; -o file:表示将 命令 结果 以 二进制 格式 存放 在 文件 中, file 是 文件名。
基本
显示 CPU 使用
情况 :统计 信息 sar -u 1 3
每隔 1 秒
统计 一次,总共 统计 3 次。 显示
内存 :使用 情况 统计 信息 sar -r 1 3
每隔 1 秒
统计 一次,总共 统计 3 次。 显示
块 :设备 统计 信息 sar -d 1 3
每隔 1 秒
统计 一次,总共 统计 3 次。 显示
网络接口 :统计 信息 sar -n DEV 1 3
每隔 1 秒
统计 一次,总共 统计 3 次。
高级
将
统计 :结果 保存 到 文件 sar -o test.txt -u 1 3
将 CPU 使用
情况 的 统计 结果 以 二进制 格式 保存 到 文件 test.txt中。从文件
中 :读取 统计 结果 sar -u -f test.txt
从文件
test.txt中读取 CPU 使用 情况 的 统计 结果。 显示
所有 :统计 信息 sar -A 1 3
每隔 1 秒
统计 一次,总共 统计 3 次,显示 所有 类型 的 统计 信息。
sar 示例
示例 1 :显示 CPU 使用
root@buildroot:~# sar -u 1 3
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
23:44:36 CPU %user %nice %system %iowait %steal %idle
23:44:37 all 0.00 0.00 0.00 0.00 0.00 100.00
23:44:38 all 0.12 0.00 0.50 0.00 0.00 99.38
23:44:39 all 0.00 0.00 0.00 0.00 0.00 100.00
Average: all 0.04 0.00 0.17 0.00 0.00 99.79
字
23:44:36:含义:采样
时间 点。表示 采样 开始 的 时间。
CPU:含义:表示
这 一行 统计 信息 所 对应 的 CPU。 all表示统计 的 是 所有 CPU 的 综合 情况。
%user:含义:用户
态 CPU 使用率。表示 CPU 在 用户 态下 运行 的 时间 占 总 时间 的 百分比。 示例:
23:44:37:0.00%,表示在 这 一秒 内, CPU 在 用户 态下 几乎 没有 运行。 23:44:38:0.12%,表示在 这 一秒 内, CPU 在 用户 态下 运行 了 0.12% 的 时间。
%nice:含义: nice 优先级
较 高 的 进程 的 CPU 使用率。表示 CPU 在 运行 nice 优先级 较 高 的 进程 时所 占用 的 时间 百分比。 示例:
23:44:37:0.00%,表示在 这 一秒 内,没有 nice 优先级 较 高 的 进程 运行。 23:44:38:0.00%,表示在 这 一秒 内,没有 nice 优先级 较 高 的 进程 运行。
%system:含义:内核
态 CPU 使用率。表示 CPU 在 内核 态下 运行 的 时间 占 总 时间 的 百分比。 示例:
23:44:37:0.00%,表示在 这 一秒 内, CPU 在 内核 态下 几乎 没有 运行。 23:44:38:0.50%,表示在 这 一秒 内, CPU 在 内核 态下 运行 了 0.50% 的 时间。
%iowait:含义: I/O 等待时间
百分比。表示 CPU 在 等待 I/O 操作 完成 时所 占用 的 时间 百分比。 示例:
23:44:37:0.00%,表示在 这 一秒 内, CPU 没有 等待 I/O 操作。 23:44:38:0.00%,表示在 这 一秒 内, CPU 没有 等待 I/O 操作。
%steal:含义:被“窃取”的
时间 百分比。在 虚拟化 环境 中,表示 CPU 时间 被 虚拟机 监视器( Hypervisor)占用 的 时间 百分比。 示例:
23:44:37:0.00%,表示在 这 一秒 内,没有 CPU 时间 被 虚拟机 监视器 占用。 23:44:38:0.00%,表示在 这 一秒 内,没有 CPU 时间 被 虚拟机 监视器 占用。
%idle:含义: CPU 空闲
时间 百分比。表示 CPU 处于 空闲 状态 的 时间 占 总 时间 的 百分比。 示例:
23:44:37:100.00%,表示在 这 一秒 内, CPU 完全 处于 空闲 状态。 23:44:38:99.38%,表示在 这 一秒 内, CPU 有 99.38% 的 时间 处于 空闲 状态。
Average::含义:表示
所有 采样 时间 点 的 平均值。 示例:
%user:0.04%,表示在 采样 期间, CPU 在 用户 态下 的 平均 使用率 为 0.04%。 %system:0.17%,表示在 采样 期间, CPU 在 内核 态下 的 平均 使用率 为 0.17%。 %idle:99.79%,表示在 采样 期间, CPU 的 平均 空闲 时间 为 99.79%。
从
在
采样 期间, CPU 的 总体 使用率 非常低,大部分 时间 CPU 处于 空闲 状态( %idle高达 99.79%)。 用户
态( %user)和内核 态( %system)的 CPU 使用率都 非常低,说明 系统 当前 的 负载 很 轻。 没有 I/O 等待(
%iowait为 0%),也没有 被 虚拟机 监视器 占用 的 时间( %steal为 0%),表明系统 运行 非常 顺畅,没有 明显 的 性能 瓶颈。
示例 2 :显示
root@buildroot:~# sar -r 1 3
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
23:45:14 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
23:45:15 357972 435880 163824 12.24 66128 688264 828364 61.88 73900 691580 4
23:45:16 357972 435880 163824 12.24 66128 688264 828364 61.88 73900 691580 4
23:45:17 357972 435880 163824 12.24 66128 688264 828364 61.88 73900 691580 8
Average: 357972 435880 163824 12.24 66128 688264 828364 61.88 73900 691580 5
字
23:45:14:含义:采样
时间 点。表示 采样 开始 的 时间。
kbmemfree:含义:空闲
的 物理 内存 量(以千 字节 为 单位)。 示例:
23:45:15:357972KB,表示在 这 一秒 内,系统 有 357972 KB 的 物理 内存 处于 空闲 状态。
kbavail:含义:可用
的 物理 内存 量(以千 字节 为 单位)。包括 空闲 内存 和 可以 回收 的 缓存 / 缓冲区 内存。 示例:
23:45:15:435880KB,表示在 这 一秒 内,系统 有 435880 KB 的 物理 内存 可供使用。
kbmemused:含义:已
使用 的 物理 内存 量(以千 字节 为 单位)。 示例:
23:45:15:163824KB,表示在 这 一秒 内,系统 有 163824 KB 的 物理 内存 被 使用。
%memused:含义:物理
内存 使用率(百分比)。 示例:
23:45:15:12.24%,表示在 这 一秒 内,系统 有 12.24% 的 物理 内存 被 使用。
kbbuffers:含义:用作
缓冲区 的 内存 量(以千 字节 为 单位)。 示例:
23:45:15:66128KB,表示在 这 一秒 内,系统 有 66128 KB 的 内存 被 用作 缓冲区。
kbcached:含义:用作
缓存 的 内存 量(以千 字节 为 单位)。 示例:
23:45:15:688264KB,表示在 这 一秒 内,系统 有 688264 KB 的 内存 被 用作 缓存。
kbcommit:含义:系统
为了 保证 当前 运行 的 进程 不会 因为 内存不足 而 失败,所 承诺 的 最小 内存 量(以千 字节 为 单位)。 示例:
23:45:15:828364KB,表示在 这 一秒 内,系统 承诺 的 最小 内存 量 为 828364 KB。
%commit:含义:承诺
的 内存 量 占 总 内存(物理 内存 + 交换 空间)的 比例(百分比)。 示例:
23:45:15:61.88%,表示在 这 一秒 内,系统 承诺 的 内存 量 占 总 内存 的 61.88%。
kbactive:含义:活跃
的 内存 量(以千 字节 为 单位)。这些 内存 是 当前 正在 使用 的,不太可能 被 回收。 示例:
23:45:15:73900KB,表示在 这 一秒 内,系统 有 73900 KB 的 活跃 内存。
kbinact:含义:不
活跃 的 内存 量(以千 字节 为 单位)。这些 内存 是 当前 未 使用 的,可能 被 回收 用于 其他 用途。 示例:
23:45:15:691580KB,表示在 这 一秒 内,系统 有 691580 KB 的 不 活跃 内存。
kbdirty:含义:脏
的 内存 量(以千 字节 为 单位)。这些 内存 包含 尚未 写入 磁盘 的 数据。 示例:
23:45:15:4KB,表示在 这 一秒 内,系统 有 4 KB 的 脏 内存。
Average::含义:表示
所有 采样 时间 点 的 平均值。 示例:
kbmemfree:357972KB,表示在 采样 期间,平均 空闲 的 物理 内存 量 为 357972 KB。 %memused:12.24%,表示在 采样 期间,物理 内存 的 平均 使用率 为 12.24%。 kbcommit:828364KB,表示在 采样 期间,系统 承诺 的 最小 内存 量 为 828364 KB。 %commit:61.88%,表示在 采样 期间,承诺 的 内存 量 占 总 内存 的 平均 比例 为 61.88%。
从
系统
的 物理 内存 使用率 较 低( %memused为 12.24%),表明系统 当前 的 内存 负载 很 轻。 大部分
内存 被 用作 缓存( kbcached为 688264 KB)和缓冲区( kbbuffers为 66128 KB),这有助于 提高 系统 的 I/O 性能。 系统
承诺 的 内存 量( kbcommit)占总 内存 的 比例 较 高( %commit为 61.88%),但实际 使用 的 内存 量( kbmemused)仍然较 低,表明 系统 有 足够 的 内存 来 满足 当前 的 运行 需求。 活跃
的 内存 量( kbactive)较少,不 活跃 的 内存 量( kbinact)较多,表明 系统 当前 运行 的 进程 对 内存 的 需求 不高。
示例 3 :显示
root@buildroot:~# sar -d 1 3
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
23:46:11 DEV tps rkB/s wkB/s dkB/s areq-sz aqu-sz await %util
23:46:12 mmcblk0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:12 mmcblk0boot0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:12 mmcblk0boot1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:12 DEV tps rkB/s wkB/s dkB/s areq-sz aqu-sz await %util
23:46:13 mmcblk0 1.00 0.00 4.00 0.00 4.00 0.00 2.00 1.00
23:46:13 mmcblk0boot0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:13 mmcblk0boot1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:13 DEV tps rkB/s wkB/s dkB/s areq-sz aqu-sz await %util
23:46:14 mmcblk0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:14 mmcblk0boot0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:14 mmcblk0boot1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: DEV tps rkB/s wkB/s dkB/s areq-sz aqu-sz await %util
Average: mmcblk0 0.33 0.00 1.33 0.00 4.00 0.00 2.00 0.33
Average: mmcblk0boot0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: mmcblk0boot1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
字
23:46:11:含义:采样
时间 点。表示 采样 开始 的 时间。
DEV:含义:磁盘
设备 的 名称。例如 mmcblk0、mmcblk0boot0等。
tps:含义:每秒
传输 的 I/O 操作 次数( transactions per second)。表示 每秒 磁盘 完成 的 I/O 操作 总数。 示例:
23:46:13:mmcblk0的tps为1.00,表示在 这 一秒 内, mmcblk0完成了 1 次 I/O 操作。
rkB/s:含义:每秒
从 磁盘 读取 的 数据量(以千 字节 为 单位)。 示例:
23:46:13:mmcblk0的rkB/s为0.00,表示在 这 一秒 内, mmcblk0没有读取 任何 数据。
wkB/s:含义:每秒
写入 磁盘 的 数据量(以千 字节 为 单位)。 示例:
23:46:13:mmcblk0的wkB/s为4.00,表示在 这 一秒 内, mmcblk0写入了 4 KB 的 数据。
dkB/s:含义:每秒
丢弃 的 数据量(以千 字节 为 单位)。通常 用于 表示 丢弃 的 写 操作。 示例:
23:46:13:mmcblk0的dkB/s为0.00,表示在 这 一秒 内, mmcblk0没有丢弃 任何 数据。
areq-sz:含义:平均
每次 I/O 操作 的 数据量(以千 字节 为 单位)。 示例:
23:46:13:mmcblk0的areq-sz为4.00,表示在 这 一秒 内,每次 I/O 操作 的 平均 数据量 为 4 KB。
aqu-sz:含义:磁盘
请求 队列 的 平均 长度。 示例:
23:46:13:mmcblk0的aqu-sz为0.00,表示在 这 一秒 内,磁盘 请求 队列 的 平均 长度 为 0 。
await:含义:从
请求 I/O 操作 到 完成 的 平均 时间(以 毫秒 为 单位)。包括 请求 队列 等待时间 和 I/O 操作 时间。 示例:
23:46:13:mmcblk0的await为2.00,表示在 这 一秒 内, I/O 操作 的 平均 等待时间 为 2 毫秒。
%util:含义:磁盘 I/O 操作
占用 CPU 的 时间 百分比。表示 磁盘 在 采样 期间 的 利用率。 示例:
23:46:13:mmcblk0的%util为1.00,表示在 这 一秒 内, mmcblk0的利用率 为 1%。
Average::含义:表示
所有 采样 时间 点 的 平均值。 示例:
tps:0.33,表示在 采样 期间, mmcblk0的平均 I/O 操作 次数 为 0.33 次 / 秒。 wkB/s:1.33,表示在 采样 期间, mmcblk0的平均 写入 数据量 为 1.33 KB/ 秒。 await:2.00,表示在 采样 期间, mmcblk0的平均 I/O 等待时间 为 2 毫秒。 %util:0.33,表示在 采样 期间, mmcblk0的平均 利用率 为 0.33%。
从
mmcblk0在采样 期间 的 I/O 活动 非常低。大部分 时间 没有 I/O 操作( tps为 0 ),偶尔有 一些 写 操作( wkB/s为 4 KB)。mmcblk0boot0和mmcblk0boot1在整个 采样 期间 没有 任何 I/O 活动。 磁盘
的 利用率( %util)非常低,表明磁盘 没有 成为 系统 的 性能 瓶颈。 平均
每次 I/O 操作 的 数据量( areq-sz)为 4 KB,表明 I/O 操作的 数据量 较 小。 I/O 操作
的 平均 等待时间( await)为 2 毫秒,表明磁盘 响应速度 较 快。
示例 4 :显示
root@buildroot:~# sar -n DEV 1 3
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
23:46:45 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
23:46:46 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:46 eth0 0.00 1.00 0.00 0.06 0.00 0.00 0.00 0.00
23:46:46 wlan0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:46 wlan1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:46 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
23:46:47 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:47 eth0 2.00 4.00 0.12 0.79 0.00 0.00 0.00 0.00
23:46:47 wlan0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:47 wlan1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:47 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
23:46:48 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:48 eth0 1.00 2.00 0.06 0.28 0.00 0.00 0.00 0.00
23:46:48 wlan0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
23:46:48 wlan1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: eth0 1.00 2.33 0.06 0.38 0.00 0.00 0.00 0.00
Average: wlan0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: wlan1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
字
23:46:45:含义:采样
时间 点。表示 采样 开始 的 时间。
IFACE:含义:网络接口
的 名称。例如 lo(本地回环 接口)、 eth0(以太网接口)、 wlan0和wlan1(无线网络接口)。
rxpck/s:含义:每秒
接收 的 数据包 数量( received packets per second)。 示例:
23:46:47:eth0的rxpck/s为2.00,表示在 这 一秒 内, eth0接收了 2 个 数据包。
txpck/s:含义:每秒
发送 的 数据包 数量( transmitted packets per second)。 示例:
23:46:47:eth0的txpck/s为4.00,表示在 这 一秒 内, eth0发送了 4 个 数据包。
rxkB/s:含义:每秒
接收 的 数据量(以千 字节 为 单位)。 示例:
23:46:47:eth0的rxkB/s为0.12,表示在 这 一秒 内, eth0接收了 0.12 KB 的 数据。
txkB/s:含义:每秒
发送 的 数据量(以千 字节 为 单位)。 示例:
23:46:47:eth0的txkB/s为0.79,表示在 这 一秒 内, eth0发送了 0.79 KB 的 数据。
rxcmp/s:含义:每秒
接收 的 压缩 数据包 数量。 示例:
23:46:47:eth0的rxcmp/s为0.00,表示在 这 一秒 内, eth0没有接收 任何 压缩 数据包。
txcmp/s:含义:每秒
发送 的 压缩 数据包 数量。 示例:
23:46:47:eth0的txcmp/s为0.00,表示在 这 一秒 内, eth0没有发送 任何 压缩 数据包。
rxmcst/s:含义:每秒
接收 的 多播 数据包 数量。 示例:
23:46:47:eth0的rxmcst/s为0.00,表示在 这 一秒 内, eth0没有接收 任何 多播 数据包。
%ifutil:含义:网络接口
的 利用率(百分比)。表示 网络接口 在 采样 期间 的 繁忙 程度。 示例:
23:46:47:eth0的%ifutil为0.00,表示在 这 一秒 内 , eth0的利用率 非常低。
Average::含义:表示
所有 采样 时间 点 的 平均值。 示例:
rxpck/s:eth0的平均值 为 1.00,表示在 采样 期间, eth0每秒平均 接收 1 个 数据包。 txpck/s:eth0的平均值 为 2.33,表示在 采样 期间, eth0每秒平均 发送 2.33 个 数据包。 rxkB/s:eth0的平均值 为 0.06,表示在 采样 期间, eth0每秒平均 接收 0.06 KB 的 数据。 txkB/s:eth0的平均值 为 0.38,表示在 采样 期间, eth0每秒平均 发送 0.38 KB 的 数据。 %ifutil:eth0的平均值 为 0.00,表示在 采样 期间, eth0的平均 利用率 非常低。
从
eth0在采样 期间 有 一些 网络 活动,主要 表现 为 发送 数据包( txpck/s和txkB/s),但接收 数据包 较 少( rxpck/s和rxkB/s)。lo(本地回环 接口)和 无线 接口 wlan0、wlan1在采样 期间 没有 任何 网络 活动。 网络接口
的 利用率( %ifutil)非常低,表明网络接口 没有 成为 系统 的 性能 瓶颈。
sar 常用命令
默认监控 : sar 5 5 // CPU 和 IOWAIT 统计状态
sar -b 5 5 // IO 传送速率
sar -B 5 5 // 页交换速率
sar -c 5 5 // 进程创建的速率
sar -d 5 5 // 块设备的活跃信息
sar -n DEV 5 5 // 网路设备的状态信息
sar -n SOCK 5 5 // SOCK 的使用情况
sar -n ALL 5 5 // 所有的网络状态信息
sar -P ALL 5 5 // 每颗 CPU 的使用状态信息和 IOWAIT 统计状态
sar -q 5 5 // 队列的长度(等待运行的进程数)和负载的状态
sar -r 5 5 // 内存和 swap 空间使用情况
sar -R 5 5 // 内存的统计信息(内存页的分配和释放、系统每秒作为 BUFFER 使用内存页、每秒被 cache 到的内存页)
sar -u 5 5 // CPU 的使用情况和 IOWAIT 信息(同默认监控)
sar -v 5 5 // inode, file and other kernel tablesd 的状态信息
sar -w 5 5 // 每秒上下文交换的数目
sar -W 5 5 // SWAP 交换的统计信息 ( 监控状态同 iostat 的 si so)
sar -x 2906 5 5 // 显示指定进程 (2906) 的统计信息,信息包括:进程造成的错误、用户级和系统级用户 CPU 的占用情况、运行在哪颗 CPU 上
sar -y 5 5 // TTY 设备的活动状态
将输出到文件 (-o) 和读取记录信息 (-f)
iozone
iozone 是
iozone 的
iperf3
iperf3 是
iperf3 的
netstat
netstat( network statistics)命令
netstat 主要
显示
活动 的 TCP 连接、 UDP 连接、路由表、接口 统计 信息 等。 列出
所有 监听 端口 及其 对应 的 服务。 显示
网络接口 的 统计 信息。 提供 IP 路由表
的 信息。 显示
网络连接 的 状态(如 建立、监听、关闭 等)。
netstat 的原理
netstat (Net Statistics) 主要netstat 的/proc/net 文件系统
netstat 的参数说明
通过netstat 命令
基本
选项 :-r,--route:显示路由表。 -i,--interfaces:显示网络接口 表。 -g,--groups:显示多播 组成员 信息。 -s,--statistics:显示网络 统计数据(类似 SNMP)。 -M,--masquerade:显示伪装 的 连接。
输出
格式 :控制 -v,--verbose:显示详细信息。 -W,--wide:不截断 IP 地址。 -n,--numeric:显示数字 格式,不 解析 主机名、端口 名 等。 --numeric-hosts:不解析 主机名。 --numeric-ports:不解析 端口 名。 --numeric-users:不解析 用户名。 -N,--symbolic:解析硬件 名称。 -e,--extend:显示更 多 的 信息。 -p,--programs:显示每个 套 接字 对应 的 进程 ID 或 程序 名。 -o,--timers:显示套 接字 定时器 信息。 -c,--continuous:持续显示 输出。
显示
类型 :控制 -l,--listening:显示监听 中 的 服务器 套 接字。 -a,--all:显示所有 套 接字(默认 只 显示 连接 的 套 接字)。 -F,--fib:显示转发 信息库( FIB)。 -C,--cache:显示路由 缓存。
Socket 类型
选项 :{ -t|--tcp }:显示 TCP 协议的 连接。 { -u|--udp }:显示 UDP 协议的 连接。 { -U|--udplite }:显示 UDPLite 协议的 连接。 { -S|--sctp }:显示 SCTP 协议的 连接。 { -w|--raw }:显示原始 套 接字 的 连接。 { -x|--unix }:显示 Unix 域套接字 的 连接。 --ax25,--ipx,--netrom:显示其他 协议 的 连接(如 AX.25 、 IPX、 NET/ROM 协议 等)。
地址
族 :选项 默认: 使用
inet地址族( IPv4 )。 IPv6: 使用
-6或--ipv6来显示 IPv6 地址。 IPv4: 使用
-4或--ipv4来显示 IPv4 地址。
支持
的 :地址 族 inet: DARPA Internet( IPv4 )。inet6: IPv6 。ax25: AMPR AX.25 协议。netrom: AMPR NET/ROM 协议。rose: AMPR ROSE 协议。ipx: Novell IPX 协议。ddp: AppleTalk DDP 协议。x25: CCITT X.25 协议。
netstat 的使用说明
使用
netstat [Options] [Address Families]
其中:
Options:用来
指定 要 查看 的 信息 类型 和 其他 行为。 Address Families:限制
显示 特定 协议 族 的 信息,如 -A inet 表示 只 显示 IPv4 的 信息。
基本
列出
所有 :当前 的 网络连接 netstat -a显示
所有 当前 的 网络连接,包括 TCP、 UDP 和 Unix 域套 接字。 列出
所有 TCP 连接 :netstat -at显示
所有 TCP 协议 的 连接。 列出
所有 UDP 连接 :netstat -au显示
所有 UDP 协议 的 连接。 禁用
反向 :域名解析 netstat -ant禁用
反向 域名解析,直接 显示 IP 地址 和 端口号,加快 查询 速度。 只
列出 :监听 中 的 连接 netstat -tnl显示
所有 处于 监听 状态 的 TCP 端口。 获取
进程 :名、进程 号 以及 用户 ID netstat -tnlp显示
每个 连接 对应 的 进程 ID 和 程序 名称。需要 root 权限。 显示
内核 :路由 信息 netstat -rn显示
内核 路由表 信息,禁用 域名解析。 打印
网络接口 :信息 netstat -ie显示
网络接口 的 详细信息,类似 于 ifconfig命令的 输出。 持续
输出 :网络连接 信息 netstat -ct持续
输出 TCP 连接 信息。 显示
多播 :组 信息 netstat -g显示 IPv4 和 IPv6 的
多播 组成员 信息。
netstat 示例
示例 1 :列出
通过 netstat -a 命令
root@buildroot:~# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:30431 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:telnet 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 208 192.168.1.10:ssh 192.168.1.101:7428 ESTABLISHED
tcp 0 0 192.168.1.10:ssh 192.168.1.101:7429 ESTABLISHED
udp 0 0 192.168.1.10:ntp 0.0.0.0:*
udp 0 0 localhost:ntp 0.0.0.0:*
udp 0 0 0.0.0.0:ntp 0.0.0.0:*
udp 0 0 0.0.0.0:319 0.0.0.0:*
udp 0 0 0.0.0.0:320 0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] SEQPACKET LISTENING 7479 /run/udev/control
unix 2 [ ] STREAM CONNECTED 8305
unix 2 [ ] DGRAM CONNECTED 8281
unix 3 [ ] STREAM CONNECTED 8280
unix 3 [ ] STREAM CONNECTED 8279
unix 3 [ ] STREAM CONNECTED 4598
unix 3 [ ] STREAM CONNECTED 7524
unix 3 [ ] STREAM CONNECTED 7528 /run/dbus/system_bus_socket
unix 3 [ ] STREAM CONNECTED 8278
unix 3 [ ] STREAM CONNECTED 8277
unix 3 [ ] STREAM CONNECTED 7523
unix 3 [ ] STREAM CONNECTED 8275
unix 3 [ ] STREAM CONNECTED 8274
unix 2 [ ] STREAM CONNECTED 14501
unix 2 [ ] DGRAM CONNECTED 368
unix 3 [ ] STREAM CONNECTED 1854
unix 3 [ ] STREAM CONNECTED 1853
unix 2 [ ] DGRAM CONNECTED 1925
unix 6 [ ] DGRAM CONNECTED 1912 /dev/log
unix 3 [ ] DGRAM CONNECTED 10244
unix 3 [ ] DGRAM CONNECTED 10243
unix 2 [ ACC ] STREAM LISTENING 1815 /run/dbus/system_bus_socket
unix 2 [ ] DGRAM CONNECTED 10459
unix 2 [ ] DGRAM 1876 /var/run/ptp4l
unix 2 [ ] DGRAM 8240 /var/run/phc2sys.569
unix 2 [ ACC ] STREAM LISTENING 8276 @jdwp-control
以下
Active Internet connections (servers and established)
TCP 连接(传输控制协议):
状态
为 LISTEN 的 :连接 0.0.0.0:30431:监听所有 IP 地址( 0.0.0.0 )上 的 端口 30431 。没有 指定 远程 连接,表示 这是 一个 开放 的 端口 等待 连接。 0.0.0.0:telnet:监听所有 IP 地址 上 的 telnet 服务(端口 23 )。同样 没有 指定 远程 连接,表示 telnet 服务 正在 监听 所有 地址 的 连接。 0.0.0.0:ssh:监听所有 IP 地址 上 的 SSH 服务(端口 22 )。表示 允许 所有 地址 的 SSH 连接。
状态
为 ESTABLISHED 的 :连接 192.168.1.10:ssh->192.168.1.101:7428和192.168.1.10:ssh->192.168.1.101:7429:这两条 是 建立 的 SSH 连接,表示 192.168.1.101(远程主机)与 本 机( 192.168.1.10)的 SSH 连接,端口分别 为 7428 和 7429 ,且 已经 处于 建立 状态,数据 可以 传输。
UDP 连接(用户
数据 :报 协议) 192.168.1.10:ntp:监听本 机 192.168.1.10上的 NTP 服务(端口 123 ),允许 接收 所有 远程 的 NTP 请求。 localhost:ntp:监听本地 回环 接口( localhost)上 的 NTP 服务。这 通常 是 用于 本 机 的 时间 同步。 0.0.0.0:ntp:监听所有 IP 地址 上 的 NTP 服务,允许 任何 来源 的 NTP 请求。 0.0.0.0:319和0.0.0.0:320:这两个 端口 监听 所有 IP 地址,但 未指定 协议 或 目的 地址,可能 是 某些 特定 的 服务。
Active UNIX domain sockets (servers and established)
UNIX 域套
接字(用于 进程 间通信): /run/udev/control:此套接字 是 udev系统管理守护 进程 用于 控制 设备 的 接口,它 在“ LISTENING”状态 下,表示 正在 等待 其他 进程 连接。 /run/dbus/system_bus_socket:这是 D-Bus 系统总线的 套 接字,多个 进程 与 系统总线 进行 通信。多个 进程 与 此套 接字 已 建立 连接,显示 为 “CONNECTED” 状态。 /dev/log:这表示 本 机上 的 日志 守护 进程(如 syslog)的 Unix 域套 接字。它 允许 本地 进程 通过 套 接字 将 日志 消息 发送到 系统日志 守护 进程。 /run/dbus/system_bus_socket(再次出现):在 Unix 域套接字 部分 出现 了 这个 路径,表示 D-Bus 系统总线 套 接字 也 在 多个 连接 中。 /var/run/ptp4l和/var/run/phc2sys.569:这两个 套 接字 路径 显示 在 “ CONNECTED” 状态,表明 它们 属于 特定 的 时钟 同步 服务。 @jdwp-control:这是用于 Java 调试 协议( JDWP)的 套 接字,通常 由 Java 调试器 使用。它 处于 监听 状态,表明 系统 中有 进程 可能 正在 等待 调试 连接。
连接
的 :状态 LISTENING:表示服务 在 等待 连接。 CONNECTED:表示该 连接 已 建立,数据 可以 在 两端 之间 传输。 DGRAM:表示数据 报套 接字,通常 用于 UDP 类型 的 通信,不 保证 可靠 传输。
从
TCP 连接:本
机 正在 监听 端口 30431 、 telnet(端口 23 )、 SSH(端口 22 )等,并且 已 与 远程 主机 建立 了 SSH 连接。 UDP 连接:本
机上 有 多个 NTP 服务 端口 正在 监听,允许 远程 和 本地 系统 进行 时间 同步。 Unix 域套
接字 :多个进程 通过 UNIX 域套 接字 与 系统 服务(如 udev、 dbus、 syslog 等)通信,且 存在 一些 调试 套 接字。
示例 2 :列出
通过 netstat -rn 命令netstat -rn 命令
root@buildroot:~# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
下面
默认
路由 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
Destination (目标
地址) :0.0.0.0表示这是 一个 默认 路由。默认 路由 指 的 是 所有 没有 在 路由表 中 明确 列出 的 目标 地址 都 会 通过 该 路由 进行 转发。 Gateway (网关):
192.168.1.1表示所有 到达 其他 网络 的 流量 将会 被 转发 到 该 网关 地址。通常 192.168.1.1是局域网 内 的 路由器 或 网关 设备 的 IP 地址。 Genmask (子网掩码):
0.0.0.0表示没有 子网掩码 要求,默认 路由 不 涉及 具体 的 子网掩码。 Flags (标志):
UG表示这个 路由 是“ Up”(活跃 的)并且 是“ Gateway”(网关 路由),即该 路由 是 作为 默认 网关 的。 MSS (最大
报文 :段 大小) 0表示没有 指定 最大 传输 单元。 Window (窗口
大小) :0表示没有 设置 窗口 大小。 irtt (RTT 估算
值) :0表示没有 设置 往返 时延( Round Trip Time)的 估算 值。 Iface (网络接口):
eth0表示该 路由 条目 适用 于 eth0网络接口。
局域网
路由 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
Destination (目标
地址) :192.168.1.0表示这是 指向 本地 子网 192.168.1.0/24的路由 条目, /24子网掩码表示 本地网络 的 地址 范围 是从 192.168.1.0到192.168.1.255。Gateway (网关):
0.0.0.0表示这 条 路由 不 需要 使用 网关,属于 本地网络 的 路由。 Genmask (子网掩码):
255.255.255.0表示子网掩码,定义 了 192.168.1.0网络的 地址 范围。 Flags (标志):
U表示这个 路由 是“ Up”的,即该 路由 可用。 MSS (最大
报文 :段 大小) 0表示没有 指定 最大 传输 单元。 Window (窗口
大小) :0表示没有 设置 窗口 大小。 irtt (RTT 估算
值) :0表示没有 设置 往返 时延 的 估算 值。 Iface (网络接口):
eth0表示该 路由 条目 适用 于 eth0网络接口。
该
默认
路由 (0.0.0.0->192.168.1.1): 所有未 明确 指定 目标 的 流量 将 被 转发 到 192.168.1.1(通常是 本地网络 的 网关 或 路由器)。 局域网
路由 (192.168.1.0/24):192.168.1.0网段上 的 流量 不 需要 经过 网关,直接 在 本地 网络接口 eth0内进行 通信。
示例3:显示
通过 netstat -tnl 命令
root@buildroot:~# netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:30431 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
以下
第一行 :
tcp 0 0 0.0.0.0:30431 0.0.0.0:* LISTENProto (协议):
tcp表示该 端口 使用 的 是 TCP 协议。 Recv-Q (接收
队列) :0表示当前 没有 在 接收 队列 中 的 数据。 Send-Q (发送
队列) :0表示当前 没有 在 发送 队列 中 的 数据。 Local Address (本地
地址) :0.0.0.0:30431表示该 服务 在 本地 监听 30431端口,0.0.0.0表示它会 接受 来自 任意 IP 地址 的 连接 请求。 Foreign Address (外部
地址) :0.0.0.0:*表示该 端口 可以 接受 来自 任意 远程 地址 的 连接。 State (状态):
LISTEN表示该 端口 处于 监听 状态,等待 来自 外部 的 连接。
第二行 :
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTENProto (协议):
tcp表示该 端口 使用 的 是 TCP 协议。 Recv-Q (接收
队列) :0表示当前 没有 在 接收 队列 中 的 数据。 Send-Q (发送
队列) :0表示当前 没有 在 发送 队列 中 的 数据。 Local Address (本地
地址) :0.0.0.0:23表示该 服务 在 本地 监听 23端口(通常用于 Telnet 服务)。 Foreign Address (外部
地址) :0.0.0.0:*表示该 端口 可以 接受 来自 任意 远程 地址 的 连接。 State (状态):
LISTEN表示该 端口 处于 监听 状态,等待 来自 外部 的 连接。
第三行 :
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTENProto (协议):
tcp表示该 端口 使用 的 是 TCP 协议。 Recv-Q (接收
队列) :0表示当前 没有 在 接收 队列 中 的 数据。 Send-Q (发送
队列) :0表示当前 没有 在 发送 队列 中 的 数据。 Local Address (本地
地址) :0.0.0.0:22表示该 服务 在 本地 监听 22端口(通常用于 SSH 服务)。 Foreign Address (外部
地址) :0.0.0.0:*表示该 端口 可以 接受 来自 任意 远程 地址 的 连接。 State (状态):
LISTEN表示该 端口 处于 监听 状态,等待 来自 外部 的 连接。
从
当前
系统 在 监听 三个 TCP 端口: 30431端口: 可能
是 某个 自定义 服务。 23端口: 用于 Telnet 服务,通常
不 推荐 在 生产 环境 中 使用,因为 Telnet 不 加密 通信。 22端口: 用于 SSH 服务,允许
远程 安全 登录。
这些
ss 的使用简介
ss (Socket Statistics) 命令
ss 的
Usage: ss [ OPTIONS ]
ss [ OPTIONS ] [ FILTER ]
-h, --help this message
-V, --version output version information
-n, --numeric don't resolve service names
-r, --resolve resolve host names
-a, --all display all sockets
-l, --listening display listening sockets
-o, --options show timer information
-e, --extended show detailed socket information
-m, --memory show socket memory usage
-p, --processes show process using socket
-i, --info show internal TCP information
--tipcinfo show internal tipc socket information
-s, --summary show socket usage summary
--tos show tos and priority information
--cgroup show cgroup information
-b, --bpf show bpf filter socket information
-E, --events continually display sockets as they are destroyed
-Z, --context display process SELinux security contexts
-z, --contexts display process and socket SELinux security contexts
-N, --net switch to the specified network namespace name
-4, --ipv4 display only IP version 4 sockets
-6, --ipv6 display only IP version 6 sockets
-0, --packet display PACKET sockets
-t, --tcp display only TCP sockets
-M, --mptcp display only MPTCP sockets
-S, --sctp display only SCTP sockets
-u, --udp display only UDP sockets
-d, --dccp display only DCCP sockets
-w, --raw display only RAW sockets
-x, --unix display only Unix domain sockets
--tipc display only TIPC sockets
--vsock display only vsock sockets
-f, --family=FAMILY display sockets of type FAMILY
FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|xdp|help}
-K, --kill forcibly close sockets, display what was closed
-H, --no-header Suppress header line
-O, --oneline socket's data printed on a single line
--inet-sockopt show various inet socket options
-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|mptcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]
-D, --diag=FILE Dump raw information about TCP sockets to FILE
-F, --filter=FILE read filter information from FILE
FILTER := [ state STATE-FILTER ] [ EXPRESSION ]
STATE-FILTER := {all|connected|synchronized|bucket|big|TCP-STATES}
TCP-STATES := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|closed|close-wait|last-ack|listening|closing}
connected := {established|syn-sent|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
synchronized := {established|syn-recv|fin-wait-{1,2}|time-wait|close-wait|last-ack|closing}
bucket := {syn-recv|time-wait}
big := {established|syn-sent|fin-wait-{1,2}|closed|close-wait|last-ack|listening|closing}
详细
性能诊断工具使用总结
对
CPU 监控
命令 :top:实时显示 系统 中 各个 进程 的 资源 占用 情况。 vmstat:报告关于 进程、内存、分页、块 I/O、陷阱 和 CPU 活动 的 信息。 mpstat:显示每个 可用 CPU 使用 情况 的 报告。 pidstat:报告每个 进程 的 CPU 使用 情况。 uptime:提供系统 整体 的 运行 状态 信息,包括 CPU 负载 情况。 sar:统计 CPU 的使用 情况,也 可以 查看 CPU 平均 负载。
内存
监控 :命令 free:显示系统 中 空闲 和 已 使用 的 物理 内存 和 交换 空间。 top:同上,也 可以 用来 监控 内存 使用 情况。 pidstat:同上,也 可以 用来 监控 内存 使用 情况。 vmstat:同上,也 可以 用来 监控 内存 使用 情况。 sar:查看内存 使用 情况。
IO 性能:
iostat:报告 CPU 和输入 / 输出 统计 信息。 vmstat:同上,也 可以 用来 监控 IO 性能。 sar:收集、报告和 存储系统 活动 信息,包括 IO 性能。 iozone:
网络
性能 :iperf3:网络性能 测试工具。 netstat:显示网络连接、路由表、接口 统计 等 信息。 sar:统计各种 网络 信息。
其他性能分析工具介绍
国际

这
以下
可
观测 性 工具 这些 工具 用于 在 系统 负载 下 观察 系统 状态。 文件系统:
lsof,pcstat,df -h,dmesg,mdadm,lvm,dmsetup,trace,pidstat -d磁盘:
iostat,iotop,strace交换
空间 :lshw,lscsil,blockdev,swapon -s,smartctl,fdisk -l,/proc/swaps
静态
性能 工具 这些 工具 可以 在 系统 空闲 时 观察 系统 状态。 BPF (Berkeley Packet Filter):
perf,ftrace,funccount,funclatency,stackcount,kprobe,uprobe,argdist,trace,profile文件系统:
ext4slower,ext4dist,btrfs*,xfs*,zfs*磁盘:
cachestat,dcsnoop,filetop,fileslower,mountsnoop
应用程序
配置 工具 这些 工具 用于 配置 和 监控 应用程序。 strace,perf trace,syncnoop,sysdig,opensnoop,statsnoop,ugc ucalls
系统
调用 接口 工具 这些 工具 用于 监控 和 分析 系统 调用。 套
接字 :tcptop,tcplife,tcpconnect,tcpaccept,tcpconnlat,tcpretransTCP/UDP:
mysqld_glower,gethostlatencyIP:
ldd,ltrace以太网:
ifconfig,ethtool,ethtool -l,ipconfig设备
驱动 :sar,perf,dstat,dmesg,journalctl,lsmod固件:
/sys/...,perf,dmesg,tiptop
文件系统
工具 VFS (虚拟
文件系统) :lsof,pcstat,df -h,dmesg,mdadm,lvm,dmsetup,trace,pidstat -d文件系统:
multipath,mdflush
调度
器 工具 cpupid,execsnoop,runlat,cpudist,offcputime,latencytop,schedtool
虚拟内存
工具 mpstat,powertop,top,htop,ps,pidstat,vmstat,slabtop,free,/proc/meminfo
时钟
源 工具 memleak,oomkill,slabratetop,numactl
设备
驱动 工具 ss,tcpdump,ip,route,iptables,iptraf-ng,dmesg
固件
工具 biosnoop,bpftrace,biosnoop,bitsize
网络
控制器 工具 lscpci,lsusb,ethtool,ifconfig
I/O 控制器
工具 iostat,iotop,strace
I/O 桥接
工具 nicstat,netstat,ip
CPU 工具
turbostat,rdmsr,cpuid,lscpu,llcstat,lstopo,capable
内存
工具 intel_gpu_top,intel_gpu_time,intel_gpu_frequency,numactl,memstat,lstopo
DRAM 工具
dramstat,dmidecode
GPU 工具
intel_gpu,gputop,nvidia-smi
I/O 工具
iostat,iotop,strace
FAN 工具
sar -m,fan,dmidecode
电源
工具 powertop
关于
4.4.12.3. 系统优化策略
CPU 优化
CPU 优化
进程
优先级 :通过管理 合理 调整 进程 的 优先级,确保 重要 进程 获得 足够 的 CPU 时间,避免 低优先级 进程 影响 系统 性能。 减少
上下文 :通过切换 优化 任务 和 进程 的 管理,减少 频繁 的 上下文 切换,提升 CPU 使用 效率。 CPU 亲和性
优化 :通过将 关键 进程 绑定 到 特定 的 CPU 核心 上,减少 CPU 迁移,提高 处理 效率。 实时性
优化 :通过启用 实时 内核 补丁 和 调整 调度 策略,减少 任务 切换 延迟,确保 实时 任务 的 及时 执行。
这些
调整进程优先级
命令:
nice和renice是用来 调整 进程 优先级 的 命令。 nice在启动 进程 时 设置 优先级, renice用于动态 调整 已 在 运行 中 的 进程 的 优先级。 目的:合理
分配 CPU 时间。通过 调整 进程 优先级,可以 确保 重要 进程 获得 更 多 CPU 时间,而 不 重要 的 进程 可以 让步,这 有助于 提升 系统 的 整体 响应 性 和 性能。 适用
场景 :在多 进程 或 多任务 环境 中,可能 会 出现 某些 进程 需要 比 其他 进程 更 多 的 CPU 资源。通过 调整 优先级,可以 避免 低优先级 的 进程 占用 过多 资源,影响 高 优先级 进程 的 执行。 示例:
# 启动一个进程并设定较低的优先级(高 nice 值) nice -n 10 command # 修改已运行进程的优先级 renice -n -10 -p <pid>
减少上下文切换
上下文
切换 :是指 CPU 在 多个 进程 或 线程 之间 切换 时,保存 和 加载 其 执行 状态(即 上下文)的 过程。频繁 的 上下文 切换 会 增加 CPU 的 负担,并 导致 性能 下降。 策略:
合并
过多 :如果的 小 任务 系统 中有 大量 的 小 任务(如 频繁 的 线程 创建 和 销毁),它们 会 导致 大量 的 上下文 切换。通过 调整 线程 池 大小、合并 任务 等 方式,可以 减少 上下文 切换 的 频率。 检查
pid_max和进程 :数 限制 pid_max参数控制 最大 进程 数,如果 系统 进程 数过 多,可能 会 导致 频繁 的 调度 和 管理,浪费 CPU 资源。适当 限制 进程 数,避免 过多 的 无用 进程 占用 资源,可以 减少 上下文 切换。
适用
场景 :在多任务 并发 环境 中,过多 的 小 任务 或 进程 会 导致 频繁 上下文 切换,从而 降低 整体 性能。减少 无用 的 进程 和 任务,有助于 提升 系统 响应速度 和 资源 使用 效率。
CPU 亲和性
定义
与 :工作 原理 CPU 亲和性(CPU Affinity):指将
某 一 进程 或 线程 绑定 到 特定 的 CPU 或 CPU 集合 上,使得 该 进程 或 线程 仅 在 指定 的 CPU 上 运行。这样 做 的 主要 目的 是 提高 进程 的 运行 效率。 原理:进程
在 运行 时会 在 CPU 缓存 中 保留 一定 的 残余 信息。如果 下 一次 运行 该 进程 时,能够 在 同一 CPU 上 执行,就 能 利用 这些 缓存 信息,避免 缓存 未 命中 的 情况,从而 减少 CPU 处理 的 负担,提升 性能。
软
亲和性 :与 硬 亲和性 软
亲和性 :操作系统调度 器(如 Linux 调度 器)会 自动 倾向 于 让 进程 保持 在 同一个 CPU 上 运行,而 不 频繁 迁移。这样 可以 减少 进程 在 多个 CPU 之间 的 切换,降低 资源 消耗,提高 系统 整体 性能。 硬
亲和性 :用户可以 通过 系统 API 手动 指定 进程 运行 在 哪个 CPU 上,从而 满足 特定 的 性能需求。例如,在 多 核 系统 中,某些 进程 可以 被 固定 在 特定 的 核心 上 运行,避免 调度 器 的 干预。
系统
的 :默认 调度 与 优化 一般
情况 下, Linux 系统 的 调度 器 已经 具备 优化 能力,默认 的 调度 策略 能够 平衡 负载 和 性能,适用 于 大多数 应用程序。 然而,针对
特定 应用,尤其 是 对 性能 要求 极高 的 任务,系统 的 通用 调度 策略 可能 不能 达到最佳 效果。这时,通过 使用 CPU 亲和性,用户 可以 手动 优化 特定 进程 的 运行 效率。
命令
taskset的应用 :命令:
taskset是 Linux 系统中 的 一个 命令,用于 将 进程 绑定 到 特定 的 CPU 核心 上,从而 避免 进程 在 多个 CPU 核心 之间 频繁 迁移(即“ CPU 迁移”)。通过 这一 方法,可以 显著 减少 由于 频繁 迁移 导致 的 缓存 失效 和 调度 开销。 目的:通过
固定 进程 到 特定 的 核心 上 运行,减少 CPU 核心 间 的 迁移,避免 调度 开销,提高 计算 效率。 适用
场景 :对于性能 要求 较 高 的 任务,特别 是 需要 高 频繁 计算 的 进程,可以 使用 taskset命令将 进程 绑定 到 特定 CPU 核心,从而 避免 多核 调度 时 产生 的 性能 损耗。 示例:
# 将进程绑定到第一个 CPU 核心上 taskset -c 0 <command>
应用
场景 :高密度
计算 :对于进程 一些 计算 密集型 进程,如果 不 希望 其 在 多个 CPU 核心 间 频繁 切换,可以 通过 CPU 亲和性 将 其 固定 到 某个 特定 的 核心 上,减少 调度 开销。 高频
交易 :例如,在场景 股票 期货 的 高频 交易 中,交易 策略 的 执行 速度 至关重要。即便 是 1ms 的 延迟 也 可能 带来 显著 的 经济损失。通过 将 交易 策略 线程 绑定 到 专用 的 CPU 上,可以 避免 线程 切换 时 的 性能 损失,确保 及时 响应。 高性能 Web 服务器(如 Nginx):在
多线程 架构 下,通过 固定 worker 进程 到 特定 的 CPU 核心,能够 减少 CPU 切换 的 损耗,从而 提升 服务器 的 处理 能力 和 响应速度。 虚拟化
技术 :在 KVM 虚拟化环境 中,通过 优化 CPU 亲和性,可以 显著 减少 虚拟机 网络 延迟,在 不 牺牲 吞吐量 的 情况 下,提升 虚拟化 环境 的 性能。
实时性优化
实时
内核 :补丁(如 PREEMPT_RT) PREEMPT_RT 是
一个 Linux 内核 补丁,旨在 提高 内核 的 实时 性能,减少 任务 切换 时 的 延迟,使得 进程 能够 更 快速 地 响应 外部 事件,确保 重要 任务 的 及时 执行。
调整
调度 :通过策略 调整 调度 策略,可以 优化 CPU 在 不同 任务 间 的 切换 效率。例如,实时 任务 可能 需要 比 普通 任务 更 高 的 优先级 或 更 低 的 延迟。 目的:减少
任务 切换 的 延迟,提升 系统 响应速度,尤其 是 需要 高度 实时性 的 应用,如 音视频 处理、实时 数据 采集 等。 适用
场景 :对于要求 高 实时性 的 应用,启用 实时 内核 和 优化 调度 策略 可以 大大提高 系统 的 响应 性,确保 时间 关键 型 任务 的 及时 执行。 示例:可以
通过 内核 配置 启用 PREEMPT_RT 补丁,并 使用 实时 调度 策略(如 SCHED_FIFO)来确保 任务 优先 执行。
内存优化
内存
Swap 管理:通过
调整 vm.swappiness参数、使用 SSD 作为 Swap 设备或者 禁用 Swap,可以 有效 提高 系统 的 内存 性能,避免 频繁 的 磁盘 I/O 操作 对系统 性能 的 影响。 透明
大页(THP) :禁用可能 引发 延迟 的 THP 可以 避免 在 高 负载 下 带来 不必要 的 性能 损失,同时 可以 根据 需要 启用 或 禁用 大页 来 提高 内存 管理效率。 OOM Killer 配置:通过
调整 oom_score_adj参数来 确保 关键 进程 在 内存 紧张 时 不 被 杀死,优先 保护 系统 中 的 重要 应用,保证系统 的 稳定 运行。
Swap 管理
vm.swappiness调整:vm.swappiness是 Linux 系统中 的 一个 内核 参数,用来 控制系统 使用 Swap 空间 的 倾向。 Swap 是 指 硬盘 上 的 一个 空间,用来 存储 暂时 不 活跃 的 内存 数据。系统 会 在 内存 压力 增大 时,将 部分 内存 数据交换 到 Swap 中。 默认
情况 下, vm.swappiness设置为 60 ,表示 系统 较 早 地 使用 Swap。如果 将 该值 调低(如 设置 为 10 ),系统 会 更 倾向 于 在 内存 压力 较 小 的 时候 使用 物理 内存,而 不 急于 使用 Swap。这样 可以 避免 Swap 空间 过早 被 使用,提升 内存 的 响应速度。 示例:通过
sysctl -w vm.swappiness=10调整该值 为 10 ,表示 减少 系统 使用 Swap 的 倾向,优先 使用 物理 内存。
使用 SSD 作为 Swap:
如果
确实 需要 使用 Swap,建议 选择 SSD 等 高性能 存储设备 作为 Swap 分区。传统 机械 硬盘 的 读写 速度 相 较 于 SSD 慢 很多,频繁 的 Swap 操作 可能 导致 严重 的 性能 瓶颈,影响 系统 的 响应 和 整体 性能。使用 SSD 可 大幅提高 Swap 访问速度,缓解 I/O 性能 瓶颈。
禁用 Swap:
在
某些 场景 下,为了 避免 磁盘 I/O 对 性能 的 影响,可能 会 考虑 完全 禁用 Swap。磁盘 I/O 操作 远慢 于 内存 访问,尤其 是 当 系统 频繁 进行 Swap 操作 时,可能 会 导致系统 性能 大幅 下降。禁用 Swap 可以 避免 系统 将 内存 数据交换 到 磁盘,从而 保证 更 快 的 内存 响应速度。
透明大页( THP)
透明
大页(Transparent Huge Pages, THP) :大页( HugePages)是
一种 内存 管理 技术,可以 减少 内存 页表 的 开销,特别 是 在 处理 大量 内存 时,能 显著 提高 内存 访问 性能。 透明
大页(THP) 是一种 自动化 的 技术,可以 在 程序运行 时 自动 将 常用 的 内存 页 合并 为 更 大 的 内存 块,从而 减少 内存 管理 的 开销,提升 性能。 然而,透明
大页 在 某些 情况 下 可能 会 引起 延迟,尤其 是 在 高 负载、高 并发 的 场景 中。此时,禁用 THP 可以 避免 由 THP 引发 的 性能 下降。 示例:通过
echo never > /sys/kernel/mm/transparent_hugepage/enabled禁用透明 大页( THP)。 说明:当前
系统 默认 没有 开启 THP 功能, Kernel menuconfig 中 没有 开启 TRANSPARENT_HUGEPAGE配置项。
OOM Killer 配置
OOM Killer:在 Linux 系统
中,当 内存 使用 达到 极限 时, OOM Killer 会 启动,它会 根据 一套 策略 选择 某个 进程 将 其 杀死,以 释放 内存。系统 会 优先 杀死 那些 消耗 最 多 内存 的 进程。 oom_score_adj参数:每个
进程 都 有 一个 oom_score_adj参数,用来调整 该 进程 被 OOM Killer 杀死 的 优先级。 oom_score_adj的值 越 高,表示 该 进程 被 杀死 的 优先级 越低,反之 越高。 通过
修改 /proc/<pid>/oom_score_adj文件,可以调整 某个 进程 的 oom_score,确保关键 任务 或 核心 进程 在 内存不足 时 不会 被 OOM Killer 杀死。 例如,给
核心 进程 设置 较 低 的 oom_score,就能 确保 它们 在 内存 耗尽 时 优先 保留,系统 会 杀死 其他 不 重要 的 进程 来 释放 内存。 示例 : 假设 有 一个 关键 进程 1234 ,希望 在 内存不足 时 优先 保留 它,可以 将 它 的 oom_score_adj 设置 为 1000 (注意 需要 有 root 权限): echo 1000 > /proc/1234/oom_score_adj
假设
有 一个 非关键 进程 5678 ,希望 在 内存不足 时 优先 杀死 它,可以 将 它 的 oom_score_adj 设置 为 -1000 (注意 需要 有 root 权限): echo -1000 > /proc/5678/oom_score_adj
调整
后,可以 通过 以下 命令 验证 设置 是否 生效: cat /proc/1234/oom_score_adj cat /proc/5678/oom_score_adj
存储优化
在
文件系统
选择 :选择专 为 闪存 设计 的 文件系统,如 UBIFS 或 F2FS,以及 启用 noatime选项,减少不必要 的 写入。 I/O 调度
器 :使用选择 适合 闪存 的 调度 器(如 noop 或 kyber),减少 I/O 调度 的 复杂性,提高 系统 响应速度。 减少
写 :通过操作 使用 tmpfs 存储 临时文件 并 压缩 日志 文件,减少 频繁 的 闪存 写入。 闪存
磨损 :通过均衡 优化 程序 的 写入 行为,避免 频繁 的 写入 热点,延长 闪存 寿命。 启用 TRIM 支持:定期
运行 TRIM 操作,清理 无用 数据 块,保持 闪存 的 高效 性能。
文件系统选择
适合
闪存 :的 文件系统 UBIFS 和 F2FS 是
为 闪存 设备(如 eMMC 和 NAND Flash)专门 设计 的 文件系统。这些 文件系统 能够 更 有效 地 管理 闪存 的 读写操作,并 优化 性能 和 耐用性。例如, F2FS 通过 减少 频繁 的 擦写 操作 来 延长 闪存 的 寿命,而 UBIFS 则 通过 优化 写入 和 垃圾 回收 机制 提高 闪存 存储 的 效率。 选择
这些 文件系统 有助于 减少 传统 文件系统(如 ext4 )在 闪存 上 的 不足,确保 闪存 设备 能 在 写入 密集 的 场景 下 维持 较长 的 使用寿命。
启用
noatime选项:noatime选项用于 防止 系统 在 每次 访问 文件 时 都 会 更新 访问 时间。通常,文件系统 会 在 每次 读取 文件 时 更新 该 文件 的 atime,这会引起 不必要 的 写入 操作,尤其 是 在 频繁 访问 的 文件 上。在 闪存 上 频繁 写入 会 加速 其 磨损,因此 启用 noatime可以有效 减少 写入 次数,延长 闪存 寿命。 通过
修改 /etc/fstab文件并 添加 noatime选项,可以减少 不必要 的 访问 时间 写入。 修改 示例 :查看
当前 的 配置 状态 root@buildroot:/userdata# cat /etc/fstab # <file system> <mount pt> <type> <options> <dump> <pass> /dev/root / ext2 rw,noauto 0 1 proc /proc proc defaults 0 0 devpts /dev/pts devpts defaults,gid=5,mode=620,ptmxmode=0666 0 0 tmpfs /dev/shm tmpfs mode=0777 0 0 tmpfs /tmp tmpfs mode=1777 0 0 tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0 sysfs /sys sysfs defaults 0 0 debugfs /sys/kernel/debug debugfs defaults 0 0 tmpfs /data tmpfs mode=1777 0 0
为
相关 的 挂载 点 添加 noatime 选项 例如,如果 想 为 根 文件系统 /启用noatime,可以将 /etc/fstab中的 条目 修改 为: /dev/root / ext2 rw,noatime,noauto 0 1
使能
配置 修改 完后,保存 文件 并 重新 挂载 文件系统,或者 重启 系统,新 的 挂载 选项 就 会 生效。重新 挂载 的 命令 可以 使用: sudo mount -o remount /
I/O 调度器选择
I/O 调度
器 :的 选择 对于 eMMC 和 NAND 闪存
设备,推荐 使用 noop 或 kyber 调度 器。这些 调度 器 比较简单,并且 在 闪存 设备 上能 减少 不必要 的 延迟。 noop 调度
器:它 基本 不 进行 复杂 的 队列 管理,适合 闪存 设备,因为 闪存 设备 本身 具有 较 低 的 访问 延迟。 kyber 调度
器:它 比 noop 更 智能 一点,但 同样 不 做 复杂 的 调度 计算,适合 低 延迟 需求 的 场景。
使用
这些 简单 的 调度 器 可以 提高 性能 并 减少 延迟,因为 它们 不 需要 进行 复杂 的 调度 计算,这 对于 I/O 较为简单 的 闪存 设备 非常 有利。 查看
当前 系统调度 器 的 方式: 通过
查看 内核 启动 日志,可以 了解 系统 支持 的 I/O 调度 器 类型。运行 以下 命令: dmesg | grep -i scheduler
示例:
root@buildroot:~# dmesg | grep -i scheduler [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies. [ 0.351393] io scheduler mq-deadline registered [ 0.351399] io scheduler kyber registered
从
结果 可以 看出,当前 系统 中 mq-deadline以及kyberI/O 调度器 已经 被 注册 并 可 用于 设备。 查看
当前 使用 的 I/O 调度 器 类型。运行 以下 命令: # 对于 EMMC 执行 cat /sys/block/mmcblk0/queue/scheduler # 对于 NAND Flash 执行 cat /sys/block/sda/queue/scheduler
示例:
root@buildroot:~# cat /sys/block/mmcblk0/queue/scheduler [mq-deadline] kyber none
从
日志 可以 看出 系统 为 设备 mmcblk0 配置 了 多种 I/O 调度 器 选项,当前 正在 使用 的 I/O 调度 器是 mq-deadline(因为它 被 方括号 [ ] 包裹 起来 了),当前 系统 还 支持 kyber和none两种 I/O 调度器: mq-deadline:这是当前 激活 的 I/O 调度 器。 mq-deadline是一种 多 队列( multi-queue) I/O 调度 器,它 是 deadline 调度 器 的 改进 版本,适用 于 多 队列 存储设备(如 NVMe SSD)。它 旨在 减少 I/O 延迟,提高 响应速度。 kyber:这是 另 一种 可用 的 I/O 调度 器,但 当前 未 被 激活。 kyber 是 一种 相对 较 新 的 I/O 调度 器,旨在 提供 更好 的 I/O 性能 和 公平性。 none:表示没有 使用 任何 I/O 调度 器。这 通常 用于 某些 特殊 场景,例如 当 设备 本身 已经 具备 高效 的 I/O 管理机制 时。
修改
当前 系统调度 器 方式: 可以 通过 以下 命令 动态 修改(需要 root 权限): echo "kyber" > /sys/block/mmcblk0/queue/scheduler
或者:
echo "none" > /sys/block/mmcblk0/queue/scheduler
注意,修改 I/O 调度
器 可能 会 影响 系统 性能,建议 在 测试环境 中 进行 调整,并 根据 实际 需求 选择 合适 的 调度 器。
减少写操作
使用 tmpfs:
tmpfs 是
一种 基于 内存 的 文件系统,常用 于 存储 临时 数据。通过 将 临时文件、缓存 文件、日志 等 存储 在 RAM 中,可以 避免 频繁 地 进行 写 操作 到 eMMC 或 NAND 闪存 中。 将
/tmp或其他 临时 目录 挂载 为 tmpfs可以大大减少 闪存 的 写入 压力,尤其 是 在 高 负载 的 嵌入式 系统 中,临时文件 的 频繁 读写 可能 会 影响 闪存 的 寿命。 # 挂载 tmpfs mount -t tmpfs tmpfs /tmp
日志
文件 :压缩 对于
嵌入式 系统 中 生成 的 日志 文件,考虑 定期 压缩 并 清理 过时 的 日志 文件,以 避免 日志 文件 不断 增加 导致 大量 写入 闪存。日志 文件 通常 会 被 频繁 写入,如果 不 加以控制,可能 会 加速 闪存 的 磨损。
闪存磨损均衡
闪存
的 :写入 次数 限制 eMMC 和 NAND 闪存
设备 具有 有限 的 写入 次数,每个 存储单元 在 一定 次数 的 写入 后 会 逐渐 失效。为了 延长 闪存 的 寿命,需要 减少 写 操作 并 避免 频繁 的 写入 热点。 通过
优化 程序 的 写入 行为、减少 不必要 的 随机 写入,并 将 热点 数据 合理 分布 到 闪存 的 不同 区域,可以 有效 减少 某些 区域 的 写入 频率,帮助 实现 磨损 均衡。
启用 TRIM 支持
TRIM 操作:
TRIM 是
一个 用于 闪存 设备 的 命令,它 可以 帮助 操作系统 告知 闪存 哪些 数据 块 不再 使用,从而 让 闪存 能够 进行 擦除 操作,释放 空间 并 优化 性能。 TRIM 操作 可以 帮助 减少 闪存 中 的 垃圾 数据,保持 存储空间 的 高效 利用。 如果
系统 启用 了 TRIM 的 支持,可以 定期 运行 fstrim命令,可以清理 无用 的 数据 块,延长 闪存 的 使用寿命 并 提高 其 性能。 说明:
当前
系统 默认 支持 TRIM 功能: root@buildroot:~# lsblk --discard NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO mtdblock0 0 0B 0B 0 mmcblk0 0 512B 3.5M 0 |-mmcblk0p1 0 512B 3.5M 0 |-mmcblk0p2 0 512B 3.5M 0 |-mmcblk0p3 0 512B 3.5M 0 |-mmcblk0p4 0 512B 3.5M 0 |-mmcblk0p5 0 512B 3.5M 0 |-mmcblk0p6 0 512B 3.5M 0 |-mmcblk0p7 0 512B 3.5M 0 |-mmcblk0p8 0 512B 3.5M 0 |-mmcblk0p9 0 512B 3.5M 0 |-mmcblk0p10 0 512B 3.5M 0 |-mmcblk0p11 0 512B 3.5M 0 |-mmcblk0p12 0 512B 3.5M 0 `-mmcblk0p13 0 512B 3.5M 0 mmcblk0boot0 0 512B 3.5M 0 mmcblk0boot1 0 512B 3.5M 0
DISC-GRAN (discard granularity) 和 DISC-MAX (discard max bytes) 列非 0 表示
该 存储设备 支持 TRIM 功能。
网络优化
网络
TCP 连接
的 :通过优化 调整 端口 范围 和 启用 TIME_WAIT 回收,提高 网络连接 的 复用 性 和 端口 的 可用性,特别 适用 于 高 并发 场景。 多核 CPU 网络
吞吐量 :通过优化 启用 RSS 和 IRQ 绑定,提升 网卡 接收 数据包 的 处理 能力,减少 CPU 瓶颈。 资源
限制 :通过优化 调整 nofile和nproc限制,确保系统 能够 处理 更 多 的 并发 连接 和 进程,适用 于 高 负载、高 并发 的 服务器 环境。
这些
TCP 参数调优
增大
本地 :端口 范围 命令:
sysctl -w net.ipv4.ip_local_port_range="1024 65535"目的:增大
本地 端口 范围,避免 端口 耗尽。通常 情况 下,操作系统 会 限制 本地 端口 范围。如果 并发 连接数 较 高,可能 会 导致 本地 端口 用尽,特别 是 在 需要 频繁 发起 大量 连接 时(例如 高 并发 的 网络应用)。通过 增大 端口 范围,可以 保证 更 多 的 应用 能够 使用 可用 端口,避免 端口 短缺 导致 的 连接 失败。 适用
场景 :高并发 网络应用,特别 是 需要 频繁 建立 连接 的 场景(如高 并发 Web 服务、数据库 连接池 等)。
启用 TIME_WAIT 连接
回收 :命令:
sysctl -w net.ipv4.tcp_tw_reuse=1目的:启用 TIME_WAIT 状态
的 连接 回收。 TCP 在 关闭 连接 后 进入 TIME_WAIT 状态,这会 占用 本地 端口,特别 是 在 高 并发 环境 下 可能 导致 端口 资源 耗尽。启用 此 配置 后,系统 会 回收 处于 TIME_WAIT 状态 的 连接,提升 端口 的 复用 率 和 利用率,避免 端口 耗尽。 适用
场景 :高并发 的 服务器 场景,特别 是 短 连接 和 频繁 建立 连接 的 应用(如 负载 均衡、 Web 服务器 等)。
网卡多队列
启用 RSS(接收端
侧 :扩展)并 绑定 IRQ 到 不同 CPU 目的:启用 RSS 能够
使 网卡 接收 的 数据包 被 分配 到 多个 CPU 核心,充分利用 多核 CPU 提高 网络 吞吐量。通常 网络流量 会 通过 单一 核心 进行 处理,可能 导致 瓶颈。通过 将 接收 到 的 数据包 分配 到 多个 CPU 内核 进行 处理,可以 有效 减少 CPU 负载 并 提高 整体 的 网络 处理 能力。 适用
场景 :高带宽、高流量 的 网络应用,尤其 是 多 核 服务器 环境 下,启用 RSS 可以 显著 提高 网络 吞吐量,减少 瓶颈。 补充
说明 :绑定 IRQ 到不同 的 CPU 核心 可以 进一步 优化 CPU 利用率,防止 某个 核心 的 过度 负载。
连接数限制
调整
nofile和nproc限制:命令:对于
嵌入式 Linxu 系统 可以 通过 修改 /etc/profile文件来 调整 nofile(文件描述符)和 nproc(进程数)限制。 目的:
nofile:限制
系统 中 每个 进程 可以 打开 的 文件 描述符 的 数量,增加 该 限制 可以 允许 更 多 的 并发 连接 或 文件 操作。 nproc:限制
系统 中 每个 用户 可以 创建 的 最大 进程 数,增大 此 限制 能够 允许 用户 启动 更 多 的 进程,适用 于 需要 启动 大量 子 进程 的 场景。
适用
场景 :高并发 服务,特别 是 需要 大量 并发 连接 的 网络应用(如 Web 服务器、数据库 连接池、大规模 分布式应用 等)。 配置
示例 :sudo vi /etc/profile # 添加下面内容 ulimit -n 65536 # 设置最大文件描述符数 ulimit -u 65536 # 设置最大进程数
4.4.12.4. 应用优化
在
Coding 原则
避免
巨量 函数调用(核心 循环 中 尽量 使用 inline 函数) 策略
分析 :函数调用会 引入 一定 的 开销,尤其 是 在 核心 循环 中 频繁 调用 时。使用 inline函数可以 在 编译 时 将 函数 代码 直接 嵌入 调用 处,从而 减少 函数调用 的 开销,提升 性能。对于 性能 要求 高 的 代码段,尤其 是 循环 中 频繁 执行 的 函数,使用 inline可以显著 提高效率。 注意:过度
使用 inline可能导致 代码 膨胀,尤其 是 函数 体 较大 的 情况 下,因为 每次 调用 都 会 将 代码 复制到 调用 点,可能 增加 二进制 文件 的 体积。
循环
无关 代码 外提 策略
分析 :循环内 的 代码 应 尽量 只 包含 循环 所 必需 的 计算,避免 在 每次 迭代 中 执行 不 相关 的 计算。循环 外提 代码 是 指 将 那些 不 依赖于 循环 变量 且 每次 迭代 都 重复 执行 的 操作 移出 循环,从而 减少 冗余 的 计算。这样 可以 有效 提升 程序 性能,尤其 是 在 循环 次数 较多时。
避免
不必要 的 内存 引用 操作 策略
分析 :内存访问 操作 通常 是 比较 耗时 的,尤其 是 对于 高 延迟 的 内存 访问(如 从 磁盘 读取数据、访问 远程 内存 等)。优化 内存 引用 意味着 减少 不必要 的 数据 访问 或 重复 访问 相同 数据。通过 合理 的 缓存 和 内存 管理,可以 减少 内存 带宽 的 消耗,提高 数据处理 速度。
守护线程优化
守护
核心
策略
分析 :守护
线程 在 后台 运行,通常 不 参与 主 业务 逻辑,因此 不 应 占用 过多 资源。线程 越 多,占用 的 系统资源 越大。 代码
复杂度 高 的 守护 线程 会 增加 计算、内存 分配 和 管理 开销,进而 影响 性能。 为
避免 性能 瓶颈,应 减少 守护 线程 数量 并 优化 代码,以 减少 内存 占用,减轻 系统调度 和 资源管理 压力,提升 整体 性能。
风险
点 :长时间
运行 的 守护 线程 可能 引发 内存 泄漏,因 其 内存 分配 和 释放 不易 察觉,导致 内存 占用 无法 释放。 在
高 并发 或 长时间 运行 的 系统 中,内存 泄漏 可能 快速 累积,降低 性能,甚至 崩溃。 因此,需要
定期检查 和 清理 守护 线程 资源,避免 内存 泄漏,确保 系统 稳定 运行。
动态库加载优化
动态
减少无用动态库的加载
策略
分析 :去掉不必要 的 动态 库。通过 减少 不必要 的 库,程序 启动 时 的 开销 和 内存 占用 都 会 减少。这是 一个 非常 直接 有效 的 优化 方式。 影响:去除
不必要 的 库后,程序 加载 的 库会 减少,进程 的 内存 占用、加载 时间 和 符号 查找 等 都 能够 得到 优化,减少 了 不必要 的 工作。
重新组织动态库的结构
策略
分析 :通过重新 组织 库 结构 来 减少 加载 的 动态 库 数量,目的 是 避免 多个 库 之间 的 冗余 加载。每个 库 应该 只 加载 必须 的 部分,避免 过多 的 库 相互依赖。 影响:这个
方法 有助于 提升 效率,减少 了 加载 的 库 数量,进而 减少 了 符号 查找、动态 链接 等 运行 时 开销。
将动态库编译为静态库
优点:
减少
了 加载 动态 库 的 数量,因为 静态 库 在 编译 时 就 被 合并 到 可执行文件 中,不再 需要 在 程序运行 时 加载。 动态
库 与 其他 库 合并 后,内部 函数调用 不再 需要 符号 查找、动态 链接,避免 了 这些 开销。
缺点:
占用
更 :当多 内存 静态 库 被 多个 进程 或 其他 库 依赖 时,它会 被 复制 多份,导致 内存 占用 增加。由于 静态 库 直接 嵌入 程序 中,不能 像 动态 库 那样 共享内存 中 的 代码段。 影响
性能 :每个进程 都 加载 自己 的 静态 库 副本,导致 内存 的 浪费。同时,由于 静态 库 增加 了 进程 的 内存 需求,可能 导致 page fault增多,从而影响 程序 的 加载 速度 和 运行 效率。
适用
情况 :当某些 动态 库仅 被 少数 进程 使用 时,编译 为 静态 库 可以 减少 启动 时 的 加载 开销。然而,对于 常驻 守护 进程 的 动态 库,静态 库 反而 不如 动态 库 高效。
使用 dlopen 动态加载动态库
优点:
精确
控制 :动态 库 的 生命周期 dlopen使得程序 能够 按 需 加载 动态 库,而 不是 在 程序 启动 时 就 加载 所有 依赖 的 库。这 可以 减少 启动 时间,并且 根据 需要 动态 管理 库 的 加载 和 卸载。 减少
内存 :通过使用 dlopen动态加载 库,可以 在 不 使用 时 卸载 库,减少 内存 中未 使用 的 部分。对于 一些 不 常用 的 库,这样 的 按 需 加载 会 节省 内存。
影响:
使用
dlopen可能增加 程序 的 复杂性,因为 它 需要 手动 管理 库 的 加载 和 卸载。这 意味着 开发者 必须 保证 在 不再 需要 库时 及时 调用 dlclose,以避免 内存 泄漏 或 其他 资源 问题。 此外,
dlopen可能增加 额外 的 性能 开销,尤其 是 在 进行 符号 解析 时。如果 没有 优化 得当,可能 导致 性能 下降。
4.4.12.5. USE 方法介绍
USE 方法的核心内容
USE 方法( Utilization Saturation and Errors Method)是USE 方法
它
Utilization(利用率):
资源
忙于 处理 工作 的 时间 百分比。 例如, CPU 使用率、磁盘 I/O 使用率。
Saturation(饱和度):
资源
因 过载 而 排队 等待 的 程度(资源 超出 其 服务 能力 的 额外 工作量,通常 表现 为 队列 长度)。 例如, CPU 运行
队列 长度、磁盘 I/O 等待 队列。
Errors(错误率):
资源
发生 的 错误 数量 或 频率。 例如,网络
丢包、磁盘 I/O 错误。
USE 方法
系统
性能 调优。 容量
规划 和 资源分配。 故障
排查 和 根因 分析。
USE 方法
快速
定位问题 :通过简单 的 指标 快速 识别 性能 瓶颈。 全面
覆盖 :适用于 硬件 和 软件资源,覆盖 系统 各个 层面。 易于
实施 :只需 检查 三个 指标,适合 所有 用户 群体。
USE 方法流程说明
列出
所有 :资源 包括 CPU、内存、磁盘、网络
等 硬件资源,以及 软件资源(如 线程 池、连接池)。
检查
每个 :资源 的 USE指标对
每个 资源,依次 检查 其 利用率、饱和度 和 错误。
识别
瓶颈 :根据
USE指标,快速定位 性能 瓶颈。
深入分析:
针对
瓶颈 资源,使用 更 详细 的 工具 和 方法 进行 深入分析。
USE 方法

下面
开始(Start):
流程
从 这里 开始,准备 进行 性能 分析。
识别
资源(Identify Resources) :确定
需要 检查 的 系统资源,包括 CPU、内存、磁盘、网络 等 硬件资源,以及 线程 池、连接池 等 软件资源。
选择
资源(Choose a Resource) :从
识别 出 的 资源 列表 中 选择 一个 资源 进行 分析。
错误
存在 :吗?(Errors Present?) 检查
选定 资源 是否 存在 错误。如果 存在 错误( Y),则 进行 下 一步 的 错误 调查。 如果
没有 错误( N),则 继续 检查 该 资源 的 利用率。
高
利用率?(High Utilization?) :检查
选定 资源 的 利用率 是否 过高。如果 利用率 高( Y),则 可能 存在 性能 瓶颈,需要 进一步 调查。 如果
利用率 不高( N),则 继续 检查 资源 的 饱和度。
饱和度?(Saturation?):
检查
选定 资源 是否 存在 饱和度 问题。如果 存在 饱和度( Y),则 表明 资源 可能 无法 处理 更 多 的 工作 负载,需要 进一步 调查。 如果
没有 饱和度( N),则 继续 检查 下 一个 资源。
所有
资源 :都 检查 完毕?(All Resources Fully Checked?) 检查
是否 所有 资源 都 已 检查。如果 所有 资源 都 已 检查( Y),则 流程 结束。 如果
还有 资源 未 检查( N),则 返回 步骤 3 ,继续 选择 下 一个 资源 进行 检查。
识别
问题(Identified the Problem?) :在
调查过程 中,检查 是否 已经 识别 出 问题。如果 已经 识别 出 问题( Y),则 返回 步骤 3 ,继续 检查 其他 资源 或 结束 流程。 如果
尚未 识别 出 问题( N),则 继续 进行 调查 和 发现( Investigate Discovery)。
调查
和 :发现(Investigate Discovery) 如果
在 前面 的 步骤 中 发现 了 问题,但 尚未 识别 出 问题 的 根本原因,则 进行 更 深入 的 调查 和 发现,以 确定 问题 的 根本原因。
结束(End):
流程
结束,所有 资源 都 已 检查,问题(如果 存在)已 被 识别。
基于 USE 理论的性能分析步骤
在USE 方法
这些USE 方法
以下
uptime:显示系统 的 平均 负载 和 运行 时间,帮助 了解 系统 负载 状况。 dmesg | tail:查看系统日志 中 的 最新 几条 消息,便于 获取 可能 的 错误 或 警告 信息。 vmstat 1:每秒显示 一次 系统 的 虚拟内存、进程 和 I/O 等 统计 信息。 mpstat -P ALL 1:每秒显示 所有 CPU 核心 的 使用 情况,帮助 检测 CPU 负载。 pidstat 1:每秒显示 进程 的 资源 使用 情况,帮助 找出 资源 占用 较 高 的 进程。 iostat -xz 1:每秒显示 I/O 设备 的 使用 情况,重点 关注 空闲 时间 较 少 的 设备。 free -m:以 MB 为单位 显示 系统 的 内存 使用 情况。 sar -n DEV 1:每秒显示 网络设备 的 性能 统计 信息。 sar -n TCP,ETCP 1:每秒显示 TCP 网络连接 的 统计 信息。 top:实时显示 系统 中 资源 占用 最高 的 进程,便于 及时 识别 资源 消耗 较大 的 进程。
需要sysstat 软件包。因此,用户sysstat 相关
BR2_PACKAGE_SYSSTAT=y
然后,重新
通过USE 方法
USE 方法的指标列表
Brendan Gregg 为 USE 方法论
例如:
CPU 利用率:使用
vmstat 1、sar -u、dstat -c等命令。 内存
利用率 :使用free -m、vmstat 1、sar -r、dstat -m等命令。 网络接口
利用率 :使用sar -n DEV 1、ip -s link、/proc/net/dev等命令。 存储设备 I/O 利用率:使用
iostat -xz 1、sar -d等命令。
详细
| component | type | metric |
|---|---|---|
| CPU | utilization | system-wide: vmstat 1, "us" + "sy" + "st"; sar -u, sum fields except "%idle" and "%iowait"; dstat -c, sum fields except "idl" and "wai"; per-cpu: mpstat -P ALL 1, sum fields except "%idle" and "%iowait"; sar -P ALL, same as mpstat; per-process: top, "%CPU"; htop, "CPU%"; ps -o pcpu; pidstat 1, "%CPU"; per-kernel-thread: top/htop ("K" to toggle), where VIRT == 0 (heuristic). [1] |
| CPU | saturation | system-wide: vmstat 1, "r" > CPU count [2]; sar -q, "runq-sz" > CPU count; dstat -p, "run" > CPU count; per-process: /proc/PID/schedstat 2nd field (sched_info.run_delay); perf sched latency (shows "Average" and "Maximum" delay per-schedule); dynamic tracing, eg, SystemTap schedtimes.stp "queued(us)" [3] |
| CPU | errors | perf (LPE) if processor specific error events (CPC) are available; eg, AMD64's "04Ah Single-bit ECC Errors Recorded by Scrubber" [4] |
| Memory capacity | utilization | system-wide: free -m, "Mem:" (main memory), "Swap:" (virtual memory); vmstat 1, "free" (main memory), "swap" (virtual memory); sar -r, "%memused"; dstat -m, "free"; slabtop -s c for kmem slab usage; per-process: top/htop, "RES" (resident main memory), "VIRT" (virtual memory), "Mem" for system-wide summary |
| Memory capacity | saturation | system-wide: vmstat 1, "si"/"so" (swapping); sar -B, "pgscank" + "pgscand" (scanning); sar -W; per-process: 10th field (min_flt) from /proc/PID/stat for minor-fault rate, or dynamic tracing [5]; OOM killer: dmesg | grep killed |
| Memory capacity | errors | dmesg for physical failures; dynamic tracing, eg, SystemTap uprobes for failed malloc()s |
| Network Interfaces | utilization | sar -n DEV 1, "rxKB/s"/max "txKB/s"/max; ip -s link, RX/TX tput / max bandwidth; /proc/net/dev, "bytes" RX/TX tput/max; nicstat "%Util" [6] |
| Network Interfaces | saturation | ifconfig, "overruns", "dropped"; netstat -s, "segments retransmited"; sar -n EDEV, drop andfifo metrics; /proc/net/dev, RX/TX "drop"; nicstat "Sat" [6]; dynamic tracing for other TCP/IP stack queueing [7] |
| Network Interfaces | errors | ifconfig, "errors", "dropped"; netstat -i, "RX-ERR"/"TX-ERR"; ip -s link, "errors"; sar -n EDEV, "rxerr/s" "txerr/s"; /proc/net/dev, "errs", "drop"; extra counters may be under /sys/class/net/...; dynamic tracing of driver function returns 76] |
| Storage device I/O | utilization | system-wide: iostat -xz 1, "%util"; sar -d, "%util"; per-process: iotop; pidstat -d; /proc/PID/sched "se.statistics.iowait_sum" |
| Storage device I/O | saturation | iostat -xnz 1, "avgqu-sz" > 1, or high "await"; sar -d same; LPE block probes for queue length/latency; dynamic/static tracing of I/O subsystem (incl. LPE block probes) |
| Storage device I/O | errors | /sys/devices/.../ioerr_cnt; smartctl; dynamic/static tracing of I/O subsystem response codes [8] |
| Storage capacity | utilization | swap: swapon -s; free; /proc/meminfo "SwapFree"/"SwapTotal"; file systems: "df -h" |
| Storage capacity | saturation | not sure this one makes sense - once it's full, ENOSPC |
| Storage capacity | errors | strace for ENOSPC; dynamic tracing for ENOSPC; /var/log/messages errs, depending on FS |
| Storage controller | utilization | iostat -xz 1, sum devices and compare to known IOPS/tput limits per-card |
| Storage controller | saturation | see storage device saturation, ... |
| Storage controller | errors | see storage device errors, ... |
| Network controller | utilization | infer from ip -s link (or /proc/net/dev) and known controller max tput for its interfaces |
| Network controller | saturation | see network interface saturation, ... |
| Network controller | errors | see network interface errors, ... |
| CPU interconnect | utilization | LPE (CPC) for CPU interconnect ports, tput / max |
| CPU interconnect | saturation | LPE (CPC) for stall cycles |
| CPU interconnect | errors | LPE (CPC) for whatever is available |
| Memory interconnect | utilization | LPE (CPC) for memory busses, tput / max; or CPI greater than, say, 5; CPC may also have local vs remote counters |
| Memory interconnect | saturation | LPE (CPC) for stall cycles |
| Memory interconnect | errors | LPE (CPC) for whatever is available |
| I/O interconnect | utilization | LPE (CPC) for tput / max if available; inference via known tput from iostat/ip/... |
| I/O interconnect | saturation | LPE (CPC) for stall cycles |
| I/O interconnect | errors | LPE (CPC) for whatever is available |
Brendan Gregg 建议
确定
监控 :首先,明确目标 需要 监控 的 系统资源,如 CPU、内存、磁盘 和 网络 等。 选择
适当 :根据的 工具 监控 目标,从 文章 中 提供 的 指标 列表 中 选择 合适 的 命令行 工具。例如,可以 使用 vmstat来监控 CPU 利用率,使用 iostat来监控 磁盘 I/O 利用率,使用 sar来监控 网络接口 利用率 等。 收集
性能 :运行数据 选定 的 工具 并 收集 性能 数据。例如,要 检查 CPU 利用率,可以 使用 以下 命令: vmstat 1:显示每秒 的 CPU 和 系统资源 使用 情况。 mpstat -P ALL 1:显示所有 CPU 的 使用 情况。 top或htop:显示进程 级别 的 CPU 使用 情况。 pidstat 1:显示每个 进程 的 CPU 使用 情况。
分析
性能 :分析数据 收集 到 的 数据,识别 利用率( Utilization)、饱和度( Saturation)和 错误( Errors)。例如,可以 检查 vmstat输出中 的“ r”值 是否 大于 CPU 核心 数,这 可能 表明 CPU 饱和。 识别
瓶颈 :通过和 错误 分析,识别系统 性能 的 瓶颈 和 错误。例如,如果 发现 CPU 利用率 过高,可能 需要 进一步 调查 是否 有 进程 占用 了 过 多 的 CPU 资源。 采取行动:根据
分析 结果,采取相应 的 优化 措施。这 可能 包括 调整 系统配置、优化 应用程序 或 升级 硬件资源。 定期
监控 :将性能 监控 作为 常规 维护 的 一部分,定期检查 系统 性能,以 确保 及时发现 并 解决 潜在 问题。 深入分析
和 :如果延迟 分析 完成 这个 检查表 后 仍然 遇到 性能 问题,可以 继续 使用 其他 策略,如 深入分析 和 延迟 分析。
4.4.12.6. 案例分析
以高 CPU 负载
编写测试用例
编写
高
负载 任务 模拟:通过 执行 密集 的 计算 任务 来 模拟 CPU 高 负载。 上下文
切换 频繁 模拟:通过 创建 大量 线程 并 让 它们 频繁 切换 来 模拟 上下文 切换 瓶颈。 中断
处理 过多 模拟:通过 模拟 硬件 中断 来 观察 CPU 处理 中断 的 情况。
测
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <sched.h>
#include <math.h>
#define NUM_THREADS 100 // 线程数量
#define MAX_TASK_COUNT 10000000000 // 每个线程的任务数量
#define MEDIUM_TASK_COUNT 1000000 // 每个线程的任务数量
// 高负载任务模拟
void* simulate_high_load_task(void* arg) {
printf("Starting high load task...\n");
// 高精度时间测量
struct timespec start, end;
double cpu_time_used;
// 获取当前时间作为开始时间
clock_gettime(CLOCK_MONOTONIC, &start);
// 执行复杂计算(大规模矩阵乘法或大规模计算)
for (long long i = 0; i < MAX_TASK_COUNT; i++) {
int result = (i * i + i) % 999999; // 更复杂的计算
}
// 获取结束时间
clock_gettime(CLOCK_MONOTONIC, &end);
// 计算任务执行时间(单位:秒)
cpu_time_used = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
// 打印任务执行时间
printf("High load task completed in %f seconds.\n", cpu_time_used);
return NULL;
}
// 线程函数
void* thread_function(void* arg) {
int id = *(int*)arg;
free(arg); // 释放线程编号的内存
printf("Thread %d started.\n", id);
for (int i = 0; i < MEDIUM_TASK_COUNT; i++) {
// 执行简单的计算任务
int result = i * i;
// 模拟线程主动放弃 CPU,触发上下文切换
usleep(100); // 休眠 100 微秒
}
printf("Thread %d finished.\n", id);
return NULL;
}
// 上下文切换频繁模拟
void* simulate_context_switching(void* arg) {
pthread_t threads[NUM_THREADS];
printf("Starting %d threads...\n", NUM_THREADS);
for (int i = 0; i < NUM_THREADS; i++) {
int* thread_id = malloc(sizeof(int));
*thread_id = i;
if (pthread_create(&threads[i], NULL, thread_function, thread_id) != 0) {
perror("Failed to create thread");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < NUM_THREADS; i++) {
if (pthread_join(threads[i], NULL) != 0) {
perror("Failed to join thread");
exit(EXIT_FAILURE);
}
}
printf("All threads completed.\n");
return NULL;
}
// 模拟中断处理函数
void handle_interrupt(int sig) {
static int count = 0;
printf("Interrupt %d handled\n", ++count);
// 执行一些计算任务,模拟 CPU 密集型工作
for (int i = 0; i < 100; i++) {
// 执行一些计算任务
int result = i * i;
}
}
// 模拟硬件中断
void* simulate_hardware_interrupt(void* arg) {
printf("Starting hardware interrupt simulation...\n");
signal(SIGALRM, handle_interrupt);
// 每 10 us 触发一次中断,模拟频繁的硬件中断
// 第一次触发的时间
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 10; // 10us
// 设置定时器周期
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 10; // 每 10us 触发一次
setitimer(ITIMER_REAL, &timer, NULL);
while (1) {
// 等待信号触发
pause();
}
return NULL;
}
// 主函数
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Usage: %s <test_cases>\n", argv[0]);
printf("Test cases:\n");
printf(" 1: High load task\n");
printf(" 2: Context switching\n");
printf(" 3: Hardware interrupt\n");
return 1;
}
pthread_t threads[4];
int test_cases[4] = {0};
for (int i = 1; i < argc; i++) {
int test_case = atoi(argv[i]);
if (test_case < 1 || test_case > 3) {
printf("Invalid test case number: %d\n", test_case);
return 1;
}
test_cases[test_case - 1] = 1;
}
if (test_cases[0]) {
pthread_create(&threads[0], NULL, simulate_high_load_task, NULL);
}
if (test_cases[1]) {
pthread_create(&threads[1], NULL, simulate_context_switching, NULL);
}
if (test_cases[2]) {
pthread_create(&threads[0], NULL, simulate_high_load_task, NULL);
pthread_create(&threads[2], NULL, simulate_hardware_interrupt, NULL);
}
for (int i = 0; i < 3; i++) {
if (test_cases[i]) {
pthread_join(threads[i], NULL);
}
}
return 0;
}
编译
arm_gcc simulate_cpu_bottleneck.c -o simulate_cpu_bottleneck -pthread -lm
其中 arm_gcc 是.bashrc 中
# ~/.bashrc
alias arm_gcc='/opt/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc'
测试分析
将simulate_cpu_bottleneck 转存chmod +x simulate_cpu_bottleneck 赋予
./simulate_cpu_bottleneck 1:高负载 任务 模拟。 ./simulate_cpu_bottleneck 2:上下文切换 频繁 模拟 ./simulate_cpu_bottleneck 3:中断处理 过多 模拟。
下面
高负载任务模拟
执行 ./simulate_cpu_bottleneck 1 后,将
top 命令:
执行
top命令后 可以 看到 如下 界面: 
分析
其中 的 关键 输出: %Cpu6 : 100.0/0.0 100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu6: 表示 CPU 核心 6 的
使用 情况。 100.0/0.0:
第一个
数字 100.0 表示 CPU 核心 6 完全 被 这个 进程 占用 了( 100% 的 用户 态 时间),即 它 的 所有 计算能力 都 被 该 进程 消耗。 第二个
数字 0.0 表示 没有 内核 态 CPU 时间 使用,也就是说,该 进程 没有 进行 系统 级 的 操作,它 完全 是 在 执行 用户 级别 的 计算 任务。
100: 该
进程 正在 占用 核心 6 的 100% 资源,这 反映 了 它 对 CPU 的 高 负载 影响。 [||||… ]: 该条
进度条 是 可视化 的 显示,表示 进程 对 CPU 资源 的 占用 程度,这里 几乎 满条,显示 进程 几乎 完全 占用 了 该 CPU 核心。
4466 root 20 0 74.8m 0.3m 100.0 0.0 3:15.18 S `- ./simulate_cpu_bottleneck 1
4466: 这是
进程 的 PID(进程 ID),表明 这是 系统 上 运行 的 进程。 root: 进程
的 所有者,这里 是 root用户。20: 进程
的 优先级。 0: 进程
的 nice 值(用于 调整 进程 的 优先级)。 74.8m: 进程
使用 的 物理 内存,表示 它 占用 了 74.8 MB 内存。 0.3m: 进程
使用 的 虚拟内存(包括 代码、数据 和 堆栈)。 100.0: 进程
使用 的 CPU 百分比,这 意味着 此 进程 正在 使用 100% 的 CPU 时间。 0.0: 进程
的 I/O 等待时间(等待 磁盘、网络 等 I/O 操作)。这里 显示 为 0 ,表示 该 进程 没有 等待 I/O。 3:15.18: 进程
的 累计 CPU 时间( 3 小时 15 分钟 18 秒),表明 该 进程 运行 了 较长时间。 S: 进程
的 状态, S 表示 该 进程 处于“睡眠”状态,但 这 是 由于 它 只是 等待 CPU 时间,实际上 它 在 活跃 执行 任务。 - ./simulate_cpu_bottleneck 1: 这是进程 的 命令行,其中 ./simulate_cpu_bottleneck 1是启动 此 任务 的 命令。
现象
解释: CPU 满负荷:从
%Cpu6行来看,进程 正在 完全 占用 CPU 核心 6 ,导致 其 使用 100% 的 计算能力。进程 可能 会 影响 其他 进程 的 性能,特别 是 在 系统 中 只有 少数 CPU 核心 时。 长时间
运行 :进程已经 运行 了 较长时间( 3 小时 15 分钟 18 秒),这 意味着 它 是 一个 计算 密集型 任务,可能 需要 大量 时间 来 完成。 内存
使用 :尽管较 低 该 进程 正在 消耗 大量 CPU 资源,但 它 的 内存 使用量( 74.8 MB)相对 较 低,表示 它 的 计算 需求 主要 是 CPU 密集型,而 不是 内存 密集型。
vmstat命令执行
vmstat 1命令,每秒更新 一次 系统 的 统计 信息。重点 关注 cpu 部分 的 内容,尤其 是 %user(用户态 CPU 时间)和 %sys(内核态 CPU 时间)。在 执行 高 负载 任务 时, %user会变高。 获取
日志 如下: root@buildroot:~# 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 0 0 0 1041108 16612 64552 0 0 2 0 53 54 42 0 58 0 0 0 0 0 1041108 16612 64552 0 0 0 0 189 231 0 1 99 0 0 0 0 0 1041108 16612 64552 0 0 0 0 42 57 0 0 100 0 0 0 0 0 1041108 16612 64552 0 0 0 0 91 112 0 0 100 0 0 0 0 0 1041108 16612 64552 0 0 0 0 79 99 0 0 99 0 0 0 0 0 1041108 16612 64552 0 0 0 12 75 99 0 0 100 0 0 0 0 0 1041108 16612 64552 0 0 0 0 73 88 0 0 100 0 0 0 0 0 1041108 16612 64552 0 0 0 0 107 100 0 1 99 0 0 0 0 0 1041108 16612 64552 0 0 0 0 41 54 0 0 100 0 0 # 执行 ./simulate_cpu_bottleneck 1 时刻 1 0 0 1041108 16612 64552 0 0 0 0 171 149 4 1 96 0 0 2 0 0 1041108 16612 64552 0 0 0 0 159 65 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 270 203 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 12 208 125 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 170 74 13 0 88 0 0 1 0 0 1041108 16612 64552 0 0 0 0 201 94 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 186 92 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 4 158 67 12 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 196 102 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 183 83 12 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 12 171 83 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 213 100 13 0 87 0 0 1 0 0 1041108 16612 64552 0 0 0 0 196 101 13 0 87 0 0 1 0 0 1041108 16612 64556 0 0 0 0 145 58 12 0 88 0 0 1 0 0 1041108 16612 64556 0 0 0 0 196 106 13 0 87 0 0 1 0 0 1041108 16612 64556 0 0 0 0 195 90 12 1 87 0 0 1 0 0 1041108 16612 64556 0 0 0 0 155 68 13 0 88 0 0 1 0 0 1041108 16612 64556 0 0 0 12 243 133 12 0 87 0 0 1 0 0 1041108 16612 64556 0 0 0 0 203 93 13 0 87 0 0 1 0 0 1041108 16612 64556 0 0 0 0 150 56 13 0 87 0 0
在
执行 测试用例 后,系统 的 状态 发生 了 些许 变化,分析 如下: 初始状态(没有
瓶颈 :时)
0 0 0 1041108 16612 64552 0 0 0 0 41 54 0 0 100 0 0
CPU:
us=0%:用户空间 没有 占用 CPU。需要 注意,这里 us是整个 CPU 所有 核心 的 总和 值。 sy=0%:内核空间 没有 占用 CPU。 id=100%: 100% 的 CPU 时间是 空闲 的,表示 没有 任何 CPU 负载。
此时,系统
没有 发生 CPU 负载,所有 进程 都 在 等待 CPU 使用 时, CPU 的 空闲 时间 达到 了 100%。 执行
simulate_cpu_bottleneck后的 :状态
1 0 0 1041108 16612 64552 0 0 0 0 170 74 13 0 88 0 0
进程:
r=1:有 1 个进程( simulate_cpu_bottleneck )在 运行 并 等待 CPU 时间,表示 现在 有 一个 进程 占用 了 CPU。 b=0:没有进程 被 阻塞,所有 进程 都 在 正常 运行。
CPU:
us=13%:用户空间 现在 占用 了 13% 的 CPU (整个 CPU 所有 核心 )时间,表示的 总和 值 模拟程序 正在 进行 一些 计算 任务,占用 CPU。 sy=0%:内核空间 几乎 没有 占用 CPU,内核 负载 较 轻。 id=88%:空闲 CPU 时间从 100% 降到 了 88%,仍 有 88% 的 CPU 时间 空闲,但 已经 有 一些 CPU 负载。
变化
分析 : 通过./simulate_cpu_bottleneck 1命令,模拟了 一个 轻微 的 CPU 负载。这个 命令 的 作用 可能 是 启动 一个 持续 占用 CPU 的 进程,因此: CPU 使用率
上升 :us=13%表示 CPU 在进行 用户 级 的 计算 任务。 空闲
时间 :空闲减少 时间 从 最初 的 100% 减少 到 了 88%。这 表明 CPU 开始 被 占用,但 仍 有 相当 多 的 空闲 时间。
结论: 执行
./simulate_cpu_bottleneck 1后,系统进入 了 一个 轻微 的 CPU 负载 状态(因为 CPU 有 8 个 核心,当前 进程 只会 跑 满 一个 核心): CPU 使用:有 13% 的
用户 空间 CPU 使用,空闲 时间 为 88%。 进程:有
一个 进程 在 运行 并 占用 CPU( r=1),没有阻塞 的 进程。 内存:内存
使用 情况 没有 明显 变化,系统 依然 保持 健康 的 内存 状态。
uptime命令执行
uptime命令显示 负载 平均值,日志 如下: 01:56:00 up 1:56, 3 users, load average: 1.00, 0.68, 2.48
分析
如下: 当前
时间 01:56:00: 当前系统 时间 为 凌晨 1 点 56 分 0 秒。 系统
运行 时间 up 1:56: 系统已经 启动 并 运行 了 1 小时 56 分钟。这个 数字 告诉 系统 自 上次 启动 以来 经过 了 多少 时间。 当前
登录 用户数 3 users: 当前有 3 个 用户 登录 到 系统 中。这 通常 包括 所有 远程 用户 和 本地用户。 负载
均值(Load Average) load average: 1.00, 0.68, 2.48: 负载均值 是 系统 过去 1 分钟、 5 分钟 和 15 分钟 的 平均 负载。这 三个 数字 分别 表示 过去 1 分钟、 5 分钟 和 15 分钟 内 系统 的 平均 负载。 1.00 (1分钟): 过去 1 分钟
的 负载 是 1.00 。这 意味着 系统 上 平均 有 1 个 进程 在 等待 CPU 时间 或 正在 使用 CPU。如果 系统 只有 1 个 核心, 1.00 表示 系统 的 CPU 利用率 达到 了 100%,但 在 多个 核心 的 情况 下,这个 负载 值 可以 更高,而 不会 造成 CPU 超负荷。
X5 总共有 8 个 核心 可以 并行处理 任务,所以 负载 1.00 是 非常 轻松 的,相当于 平均 每个 核心 都 在 忙碌 地 处理 一个 任务。这个 值远 低于 核心 数,因此 系统 的 负载 非常 轻,不会 有 性能 瓶颈。 0.68 (5分钟): 过去 5 分钟
的 负载 是 0.68 。这个 负载 低于 1.00 ,表明 在 这 段时间 内,系统 负载 较 轻,没有 超过 系统 处理 能力。 2.48 (15分钟): 过去 15 分钟
的 负载 是 2.48 。相比 于 1 分钟 和 5 分钟 的 负载,过去 15 分钟 的 负载 较 高,接近 2.5 。但 系统 有 8 个 核心,负载 为 2.48 表示 在 大部分 时间 里,每个 核心 只 需要 处理 少量 的 任务,因此 系统 依然 能够 轻松 应对 这种 负载。
负载
均值 的 解释: 负载
均值 衡量 的 是 系统 处理 任务 的 能力,通常 它 是 系统 CPU 核心 数量 的 一个 参考 指标。一般来说,负载 均值 等于 或 接近 CPU 核心 数时,系统 的 CPU 就 达到 了 满负荷,超过 了 核心 数会 导致 进程 积压,可能 出现 性能 下降。 如果
系统 有 1 个 核心 ,那么 1.00 的负载 意味着 系统 CPU 已经 被 充分 使用(没有 空闲)。如果 负载 更高(比如 2.48 ),则 表示 系统 有 超过 1 个 进程 同时 等待 执行。 如果
系统 有 多个 核心 ,例如 8 个核心,负载 为 2.48 则 意味着 CPU 负载 没有 达到 系统 的 最大 处理 能力。 8 个 核心 可以 轻松 处理 负载 2.48 ,系统 仍然 能够 保持 平稳 运行。
负载
过高 的 标准: 8 个
核心 的 系统 最大 负载 应为 8.00 。如果 负载 均值 接近 或 超过 8.00 ,那么 可能 会 有 进程 开始 排队,系统 的 性能 可能 会 出现 瓶颈,导致 延迟。 负载
为 2.48 ,表示 系统 远 未 达到 核心 数 的 最大 负载, CPU 资源 充足,系统 不会 出现 性能 问题。
结论:
根据
日志,系统 的 负载 均值 远 低于 8 个 核心 的 最大 负载,表明 当前 系统 的 负载 非常 轻松, CPU 资源 充裕。 即使
是 过去 15 分钟 的 负载 值( 2.48 )也 不会 对系统 性能 造成 压力,系统 有 足够 的 处理 能力 来 应对 当前任务。
mpstat命令mpstat命令可以 输出 各个 CPU 核心 的 使用 情况,详细 说明 了 每个 核心 的 各项 CPU 时间 指标。 root@buildroot:~# mpstat -P ALL 1 Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 aarch64 (8 CPU) 01:56:45 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01:56:46 all 12.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 87.53 01:56:46 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 01:56:46 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
命令
输出 说明 如下: 系统
信息 :
Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU)
系统
使用 的 是 Linux 6.1.83内核,架构为 aarch64,共有 8 个 CPU 核心。总体
的 CPU 使用 :情况
01:56:45 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01:56:46 all 12.47 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 87.53
all行:表示所有 核心 的 总和。 %usr=12.47%: 12.47% 的 CPU 时间用于 执行 用户 空间 进程(非 内核 进程)。 %nice=0.00%:没有进程 以 调整 优先级( nice)的 方式 运行。 %sys=0.00%:没有 CPU 时间用于 内核 空间 操作。 %iowait=0.00%:没有等待 I/O 操作 的 时间。 %irq=0.00%:没有 CPU 时间用于 处理 中断。 %soft=0.00%:没有 CPU 时间用于 处理 软 中断。 %steal=0.00%:没有 CPU 时间被 虚拟化 系统 抢占。 %idle=87.53%: 87.53% 的时间 CPU 处于 空闲 状态。
从
all行来看,系统 的 CPU 使用 情况 非常 轻松,大部分 时间 CPU 都 处于 空闲 状态。 各个
核心 :的 CPU 使用 情况 01:56:46 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 3 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 01:56:46 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 01:56:46 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
每
一行 表示 一个 CPU 核心 的 使用 情况,从 CPU 0 到 CPU 7(共 8 个 核心)。 核心 0 到 2 、 4 到 7 :
%usr=0.00%:这些核心 在 用户 空间 的 CPU 时间 为 0%,意味着 没有 用户 进程 在 这些 核心 上 运行。 %idle=100%:这些核心 完全 处于 空闲 状态,没有 任务 在 运行, CPU 处于 空闲 状态。
核心 3 :
%usr=100.00%:核心 3 完全被 用户 进程 占用,所有 的 CPU 时间 都 用于 执行 用户 空间 的 进程。 %idle=0.00%:核心 3 没有空闲 时间,完全 在 忙碌 地 处理 任务。
综上
可以 看出: CPU 总体
使用 :情况 系统
总 的 12.47%CPU 时间用于 用户 空间 任务, 87.53%时间空闲,说明 系统 负载 较 轻,大部分 时间 CPU 没有 被 充分利用。
各个
核心 :的 分布 情况 核心 3 的
负载 非常 高,几乎 100% 的 时间 都 在 处理 用户 进程。其他 核心(如 核心 0 到 2 、 4 到 7 )几乎 处于 空闲 状态,这 可能 表明 某个 特定 任务 或 进程 集中 在 核心 3 上 运行。
没有 I/O 或
中断 :等待 iowait、irq和softirq都是 0 ,表示 系统 没有 因 I/O 操作 或 中断 而 导致 CPU 等待。
结论:
该
系统 在 这个 时刻 的 负载 非常 轻松,大多数 CPU 核心 空闲,只有 一个 核心(核心 3 )被 100% 占用。 系统
整体 性能 非常 平稳,没有 出现 瓶颈,空闲 资源 充足。如果 这个 状态 持续,系统资源 使用 较为 均衡。
实现
mpstat命令类似 效果 的 还 可以 执行 sar -P命令:root@buildroot:~# sar -P ALL 5 5 Linux 6.1.83-DR-PL5.1_V1.0.16 (buildroot) 01/01/70 _aarch64_ (8 CPU) 02:26:06 CPU %user %nice %system %iowait %steal %idle 02:26:11 all 12.51 0.00 0.18 0.00 0.00 87.32 02:26:11 0 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 1 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 2 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 3 100.00 0.00 0.00 0.00 0.00 0.00 02:26:11 4 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 5 0.20 0.00 1.40 0.00 0.00 98.40 02:26:11 6 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 7 0.00 0.00 0.00 0.00 0.00 100.00 02:26:11 CPU %user %nice %system %iowait %steal %idle 02:26:16 all 12.57 0.00 0.10 0.03 0.00 87.30 02:26:16 0 0.00 0.00 0.20 0.20 0.00 99.60 02:26:16 1 0.00 0.00 0.00 0.00 0.00 100.00 02:26:16 2 0.00 0.00 0.00 0.00 0.00 100.00 02:26:16 3 100.00 0.00 0.00 0.00 0.00 0.00 02:26:16 4 0.00 0.00 0.00 0.00 0.00 100.00 02:26:16 5 0.60 0.00 0.60 0.00 0.00 98.80 02:26:16 6 0.00 0.00 0.00 0.00 0.00 100.00 02:26:16 7 0.00 0.00 0.00 0.00 0.00 100.00
优化
策略 通过
上述 几个 工具 即可 监控 和 分析 CPU 的 负载 情况,可以 观察 到 高 负载 任务 对 CPU 的 影响,特别 是 CPU 使用率 的 增加。进行 性能 分析 的 时候 需要 通过 多种 命令 查看 CPU 的 整体 使用 状态 以及 各个 CPU 核 的 使用 状态。 执行
高 负载 任务 时,常见 的 现象 主要 包括: 高
%user和%sys值,表示大量 的 用户 态 和 内核 态 计算。 top或htop中某个 进程 占用 了 大量 的 CPU 资源。 iowait和idle时间较 低,表明 CPU 大量 处于 活跃 状态,较 少有 空闲 时间。
在
实际 的 工程 情景 中,如果 遇到 类似 的 情况 需要 进行 性能 优化,可以 考虑 以下 策略: 减少
计算 复杂度:分析 高 负载 任务 的 代码 逻辑,寻找 可以 优化 的 算法 或 数据结构,减少 不必要 的 计算。 并行
化 任务:将 任务 分解 为 多个 子 任务,并行执行 以 充分利用 多核 CPU 的 优势。例如,使用 多线程 或 异步 编程 模型。
上下文切换频繁模拟
执行 ./simulate_cpu_bottleneck 2 后,将
时间
片用 :线程完 运行 了 一段时间 后,时间 片用 完,操作系统 会 切换 到 其他 线程。 等待
资源 :线程主动 调用 sleep 或 等待 I/O 操作,操作系统 会 切换 到 其他 线程。 线程
间 :线程同步 之间 通过 锁 或 其他 同步 机制 进行 通信,导致 线程 阻塞 和 切换。
为了
可以
top命令执行
top命令后 可以 看到 如下 界面: 
以下
是 对系统 当前 状态 的 分析: CPU 使用
情况 系统有 8 个 CPU 核心,分别 是 Cpu0到Cpu7。每个核心 的 使用 情况 如下: %CpuX 统计
的 数字 分为 两 部分: 第一
部分(例如 3.1 )是 当前 的 CPU 使用率。 第二
部分(例如 80.9 )是 CPU 在 当前 时间段 内 的 空闲 率。
例如:
%Cpu0:使用
了 3.1%,空闲 了 80.9%。 %Cpu1:使用
了 3.3%,空闲 了 78.9%。 %Cpu2:使用
了 2.3%,空闲 了 80.5%。 以此类推,所有 CPU 核心
的 使用 情况 都 相对 较 低,但 总体 看,系统 中 每个 核心 的 空闲 率 较 高(大部分 都 在 78% 以上)。
这
表明 虽然 负载 较 高,但 每个 核心 的 利用率 相对 较 低,可能 意味着 进程 是 I/O 密集型 或 进程 数量 较 多,导致 CPU 时间 没有 被 完全 占用。
分析
总结 :高
负载 :负载平均值 非常 高,尤其 是 1 分钟 负载( 17.48 )远超 系统 的 CPU 核心 数。这 可能 意味着 系统 有 较 多 的 进程 等待 CPU 时间,或 CPU 的 某些 操作(如 I/O 请求)导致 了 阻塞。 CPU 空闲
率 :虽然较 高 系统 负载 高,但 每个 核心 的 空闲 率 都 在 70%-80% 之间,说明 CPU 并未 完全 占用,可能 是 I/O 或 其他 资源 导致 了 系统 的 延迟。 内存
充足 :内存使用量 很 低(仅 1.3 GiB),并且 交换 空间 也 未 被 使用,表明 内存 不是 当前 性能 瓶颈。 任务
分布 :大部分进程 处于 睡眠 状态,可能 是 在 等待 某些 I/O 操作 完成。 1 个 运行 中 的 任务说明 当前 活跃 进程 较 少,负载 可能 来自 少数几个 进程。
vmstat命令主要
关注 vmstat命令输出 中 的 cs( context switches )属性的 值,启动 进程 后,日志 如下: root@buildroot:~# 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 0 0 0 1043028 17984 60580 0 0 0 0 78 90 0 0 100 0 0 0 0 0 1043028 17984 60580 0 0 0 0 38 55 0 0 100 0 0 0 0 0 1043028 17992 60580 0 0 0 12 109 133 0 0 99 0 0 0 0 0 1043028 17992 60580 0 0 0 0 95 110 0 0 99 0 0 # 执行 ./simulate_cpu_bottleneck 2 时刻 19 0 0 1040764 17992 60580 0 0 0 0 262464 682330 3 72 25 0 0 40 0 0 1040764 17992 60580 0 0 0 0 262257 668847 3 80 17 0 0 53 0 0 1040764 17992 60580 0 0 0 0 253638 651784 2 83 16 0 0 31 0 0 1040764 17992 60580 0 0 0 0 246351 636829 3 81 16 0 0 42 0 0 1040764 17992 60580 0 0 0 0 254587 654205 2 82 16 0 0 29 0 0 1040516 17992 60580 0 0 0 0 249660 643429 3 81 15 0 0
以下
是 详细 的 分析: 关键
指标 :解释 cs(Context Switches per second):每秒上下文 切换 的 次数。上下文 切换 是 指 CPU 从 一个 进程 或 线程 切换 到 另 一个 进程 或 线程 的 过程 。 in(Interrupts per second):每秒中断 的 次数,包括 时钟 中断 。 us(User CPU time):用户态 CPU 使用率,表示 用户 进程 占用 CPU 的 时间 百分比 。 sy(System CPU time):内核态 CPU 使用率,表示 内核 进程 占用 CPU 的 时间 百分比 。 id(Idle CPU time): CPU 空闲时间,表示 CPU 未 被 任何 进程 占用 的 时间 百分比 。
上下文
切换 :的 显著 变化 初始状态:
cs的值 为 110 ,表示 每秒 发生 110 次 上下文 切换。 系统
整体 运行 平稳, CPU 空闲 时间 较 高( id为 99%)。
运行
simulate_cpu_bottleneck后:cs的值 显著 增加,达到 682330 ,表示 每秒 发生 682330 次 上下文 切换。 in的值 也 显著 增加,达到 262464 ,表示 每秒 发生 262464 次 中断。 CPU 使用率
发生变化, us为 3%,sy为 72%,id为 25%,表明系统 态 CPU 使用率 大幅 增加,而 用户 态 CPU 使用率 相对 较 低。
分析:
上下文
切换 :增加 的 原因 simulate_cpu_bottleneck程序可能 创建 了 大量 线程 或 进程,并且 这些 线程 或 进程 频繁 地 放弃 CPU(例如 通过 调用 sleep或其他 同步 机制),导致 操作系统 频繁 地 进行 上下文 切换 。 高频率
的 上下文 切换 会 增加 内核 态 CPU 使用率( sy),因为上下文 切换 主要 由 内核 完成 。
中断
次数 :增加 的 原因 频繁
的 上下文 切换 会 触发 内核 中 的 中断 处理程序,用于 管理 线程 的 切换 和 调度 。 这些
中断 主要 是 软件 中断( softirq),用于处理 内核 任务,如 调度 和 时间 管理 。
CPU 使用率
变化 :的 原因 高频率
的 上下文 切换 导致 内核 态 CPU 使用率( sy)显著增加,而 用户 态 CPU 使用率( us)相对较 低 。 程序
可能 主要 在 内核 态 执行 任务,例如 线程 同步 或 系统 调用 。
总结: 运行
simulate_cpu_bottleneck程序后, vmstat显示的 上下文 切换 次数( cs)和中断 次数( in)显著增加,这 表明 程序 触发 了 大量 的 上下文 切换 和 内核 活动。这种 行为 是 由于 程序 创建 了 大量 线程,并且 这些 线程 频繁 地 放弃 CPU,导致 操作系统 频繁 地 进行 上下文 切换 。
perf命令上述
top命令的 输出 中 可以 看到 simulate_cpu_bottleneck的 PID 是 7321 ,可以通过 perf stat -p 7321命令来 获取 该 进程 的 性能 统计 信息: root@buildroot:~# perf stat -p 7321 Performance counter stats for process id '7321': 214343.34 msec task-clock # 5.221 CPUs utilized 14317887 context-switches # 66.799 K/sec 134 cpu-migrations # 0.625 /sec 0 page-faults # 0.000 /sec 281409199909 cycles # 1.313 GHz 118189146222 instructions # 0.42 insn per cycle 15410712830 branches # 71.897 M/sec 1651506356 branch-misses # 10.72% of all branches 41.051394519 seconds time elapsed
从
perf stat输出来看,进程 7321(simulate_context_switching)在运行 期间 表现 出 以下 特点: 性能指标
分析 :task-clock:214343.34 msec:表示
进程 总共 运行 了 214.34 秒 的 CPU 时间。 5.221 CPUs utilized:表示
平均 有 5.221 个 CPU 核心 被 该 进程 占用。这 表明 进程 在 多 核上 并行 运行,且 CPU 利用率 较 高。
context-switches:14317887:表示
总共 发生 了 14317887 次 上下文 切换。 66.799 K/sec:表示
平均 每秒 发生 66799 次 上下文 切换。这是 一个 非常 高 的 频率,表明 线程 频繁 地 放弃 CPU,导致 调度 器 频繁 切换 线程。
cpu-migrations:134:表示
线程 在 不同 CPU 核心 之间 迁移 了 134 次。 0.625 /sec:表示
平均 每秒 发生 0.625 次 CPU 迁移。这个 值 相对 较 低,表明 线程 主要 在 固定 的 CPU 核心 上 运行,没有 频繁 地 跨 核心 迁移。
page-faults:0:表示
没有 发生 页面 错误。这 表明 程序 的 内存 访问 非常 高效,没有 触发 缺页 中断。
cycles:281409199909:表示
总共 发生 了 281409199909 个 CPU 时钟 周期。 1.313 GHz:表示
平均 CPU 时钟 频率 为 1.313 GHz。
instructions:118189146222:表示
总共 执行 了 118189146222 条 指令。 0.42 insn per cycle:表示
平均 每条 指令 需要 0.42 个 时钟 周期。这 表明 指令 执行 效率 较 高,但 仍 有 优化 空间。
branches:15410712830:表示
总共 发生 了 15410712830 次 分支 指令。 71.897 M/sec:表示
平均 每秒 发生 71897000 次 分支 指令。
branch-misses:1651506356:表示
总共 发生 了 1651506356 次 分支 预测 失败。 10.72% of all branches:表示
分支 预测 失败率 约 为 10.72%。这是 一个 相对 较 高 的 比例,表明 程序 的 分支 预测 效率 较 低。
从
上述 性能 分析 结果 可以 得出 高频 上下文 切换 的 原因 : 线程
频繁 :放弃 CPU 程序
中 每个 线程 都 频繁 地 调用 usleep(1),这导致 线程 主动 放弃 CPU,触发 上下文 切换。 每次
调用 usleep(1)会使 线程 进入 睡眠 状态,调度 器会 切换 到 其他 线程 运行。
线程
数量 :多 创建
了 大量 线程( 100 个),每个 线程 都 在 频繁 地 放弃 CPU,导致 调度 器 需要 频繁 地 切换 线程。
高频率
的 上文 切换 进而 导致 了 高 CPU 占用: 频繁
的 :上下文 切换 每次
上下文 切换 都 需要 内核 介入,这 增加 了 内核 态 的 CPU 使用率( sy)。高频率
的 上下文 切换 导致系统 负载 增加, CPU 占用率 升高。
线程
任务 :简单 每个
线程 的 任务 简单( i * i),计算量 小,但 线程 数量 多,导致 整体 CPU 使用率 较 高。
优化
策略 :在
实际 工程 情景 中,如果 遇到 类似 频繁 上下文 切换 的 情况,在 需要 进行 性能 优化 时,可以 考虑 以下 策略: 减少
线程 数量:减少 线程 或 进程 的 数量,优化 线程 任务,或者 调整 线程 调度 策略,以 减少 上下文 切换 的 频率 。 增加
线程 任务 的 复杂性:优化 线程 任务,使 线程 在 时间 片内 完成 更 多 工作,减少 主动 放弃 CPU 的 次数,以 减少 上下文 切换。 调整
线程 的 调度 策略:例如 使用 实时 调度 策略,减少 上下文 切换。 使用
线程 池:使用 线程 池来 复用 线程 资源,减少 线程 创建 和 销毁 的 开销。线程 池 可以 有效 减少 上下文 切换 次数。
中断处理过多模拟
执行 ./simulate_cpu_bottleneck 3 后,测试用例
1. 频繁
定时器
设置 :setitimer设置了 一个 定时器,每 10us 触发 一次 SIGALRM信号。这种
高频率 的 信号 触发 模拟 了 硬件 设备 频繁 产生 中断 的 情况。
2. CPU 密集型
信号处理
函数 :每次
信号 触发 时, handle_interrupt函数会 被 调用。 在
handle_interrupt函数中,执行 了 一个 简单 的 计算 任务( i * i),模拟 CPU 密集型的 中断 处理 工作。 这种
计算 任务 会 占用 一定 的 CPU 时间,导致 CPU 负载 增加。
3. 阻塞
pause()函数:在
simulate_hardware_interrupt函数中,线程 通过 pause()函数进入 阻塞状态,等待 信号 触发。 每次
信号 触发 后,线程 会 从 阻塞状态 中 唤醒,执行 信号处理 函数,然后 再次 进入 阻塞状态。
可以
top命令执行
top命令后 可以 看到 如下 界面: 
可以
看到 多个 CPU 均 有 一定 的 占用率。
vmstat命令主要
关注 vmstat命令输出 中 的 in( interrupt )属性的 值,启动 进程 后,日志 如下: root@buildroot:~# 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 1066280 4232 53984 0 0 7 0 1796 2427 14 10 75 0 0 0 0 0 1065808 4240 53976 0 0 0 12 9254 9351 1 2 97 0 0 2 0 0 1066032 4240 53984 0 0 0 0 157572 155101 9 30 61 0 0 0 0 0 1065776 4240 53984 0 0 0 0 115187 114196 6 22 71 0 0 4 0 0 1066128 4240 53984 0 0 0 12 28050 27335 2 6 93 0 0 3 0 0 1066192 4240 53984 0 0 0 0 179452 176975 10 34 56 0 0 0 0 0 1066192 4240 53984 0 0 0 0 66883 65707 4 12 84 0 0 2 0 0 1066128 4240 53984 0 0 0 0 89418 87806 5 16 78 0 0 4 0 0 1066448 4240 53984 0 0 0 0 179625 176706 11 34 55 0 0 0 0 0 1066352 4248 53984 0 0 0 12 5678 5793 0 1 98 0 0 2 0 0 1065456 4248 53984 0 0 0 0 113790 111781 7 21 72 0 0 0 0 0 1065680 4248 53984 0 0 0 0 162102 159638 8 32 60 0 0 0 0 0 1065680 4248 53984 0 0 0 0 95 114 0 0 100 0 0
可以
看到 in属性的 值 非常 大,说明 产生 了 大量 的 中断,进程 模拟 产生 了 中断 风暴 。 而且,观察到, cs的数值 也 非常 高。这 通常 与 系统 负载 较 高、任务调度 频繁 有关。
在
高频
网络 数据包 引发 的 中断。 高速
磁盘操作 所 产生 的 中断。 系统
中 存在 频繁 触发 的 定时器 中断(例如 高频 硬件 定时器)。
中断
当
in(中断次数)和 cs(上下文切换 次数)值 都 非常 高,并且 二者 同步增长 时,通常 表示 系统 正 面临 大量 硬件 中断。这些 中断 可能 导致 CPU 在 处理 中断 时 频繁 进行 上下文 切换,从而 引发 中断 风暴 。中断
风暴 的 核心 原因 在于 系统 不断 接收 大量 中断请求,迫使 系统 持续 响应 这些 中断 并 频繁 切换 任务。这种 现象 可能 会 导致 CPU 过载,显著 降低 系统 性能。
优化
针对
检查
系统 中 哪些 进程 或硬件 设备 生成 了 过 多 的 中断,并 找出 根源。 优化
硬件 设备 的 中断 处理 机制,尽量减少 不必要 的 中断 触发。 分析
系统 的 调度 策略,优化 进程 调度 和 任务 处理 方式,确保 资源 的 合理 分配 和 系统 的 高效 运行。