新闻详情

新闻详情

首页 / 资讯中心 / 详情

性能测试内存分析实战:free、vmstat、sar三工具排查链路

发布时间:2026/9/26 16:48:07来源:尧图网络
性能测试内存分析实战:free、vmstat、sar三工具排查链路
做了这么多年性能测试我越来越觉得内存分析是三大件里最容易被“差不多”糊弄过去的一环。CPU 飙起来一眼就能看见磁盘 IO 慢下来监控曲线也骗不了人唯独内存很多人压测时就是敲一下 free看到 used 不高就放行了结果压测跑到一半 TPS 莫名掉底再回头看 vmstat 和 sar 才追悔莫及。这篇文章想把我日常压测里用 free、vmstat、sar 做内存分析的方法完整讲一遍每个工具到底在告诉你什么、哪些字段才是真正需要盯的、三个工具怎么串成一条排查链路。适合同样在做压测但被内存问题绕晕的测试开发同学也适合刚接触性能测试、想建立系统资源分析体感的新人。文章不会只停留在“参数是什么”的层面我会把内核在背后做的那些事一起讲透因为看不懂背后逻辑你就永远只能背参数。1. free 命令一次快照背后是内核的缓存与回收策略1.1 逐列拆解 free 的输出真正的主语是“可回收”拿最普通的free -h输出说话$ free -h total used free shared buff/cache available Mem: 15Gi 7.4Gi 987Mi 356Mi 7.5Gi 7.7Gi Swap: 8.0Gi 0B 8.0Gitotal 是物理内存总量内核在启动阶段探测后基本固定。used 的官方定义是total - free - buff/cache也就是说 used 里并不包含 buff/cache 部分。free 是真正“没人碰过”的空闲页而 shared 指的是 tmpfs 这类文件系统占用的内存多进程共享内存也会体现在这一列。但我最想让压测同学先改掉的习惯是第一眼看 available不是看 free更不是看 used。available 是内核 3.14 之后才加入的估算值含义是“在不触发明显 swap 的前提下新进程还能申请到多少内存”。内核算这个数的时候会统计可回收的 page cache、可回收的 slab扣除正在被使用的内核内存所以它通常比 free 大得多也更接近“真实还能用的内存水位”。压测中最常见的第一类误判就是把 free 列当成“剩余内存”。一台机器 free 列只剩 200MB但 available 还有 12GB这时候你根本不用慌反过来free 列剩 4GBavailable 只有几百 MB那问题已经迫在眉睫了。两者的差异本质上就是内核有多少缓存页“随时可以被回收”。1.2 buff/cache 不是“已用内存”而是内核的弹性缓冲池很多初学性能测试的人第一次看到 buff/cache 占了快一半内存都下意识觉得“完了内存被吃光了”。其实恰恰相反buff/cache 是内核主动做的一次“投资”空闲内存闲着也是闲着不如拿来缓存读过写过的文件块下次再用的时候直接命中不用重新走磁盘。buffer 和 cache 在早期内核里分得比较清楚buffer 主要面向块设备缓存文件系统元数据和脏块cache 主要面向文件页缓存。现代内核里两者边界已经很模糊了所以 free 从 3.x 开始干脆合并成 buff/cache 一列。这个设计有点像家里囤日用品冰箱里囤的菜不是浪费而是在降低“下次买菜”的成本。真到没米下锅的时候你也能把囤的菜吃掉再出门——这些缓存页就是可以“吃”的那部分。内核在内存紧张时通过 shrink 机制回收 page cache把脏页写回磁盘腾出物理页给用户程序使用。所以 buff/cache 高不等于内存有压力相反它在大多数情况下是好事。真正要警惕的信号是 available 持续走低、同时 swap 区域开始出现动静那说明系统连“可回收的弹性空间”都快掏空了这正好接上下面的实战内容。1.3 free 的实战姿势频率、参数和数据解读习惯压测期间 free 不能只敲一次。它更像一张照片而压测是两三个小时的过程你要的是连续照片组成的相册。我习惯这样用free -h -s 5每 5 秒刷新一次既能感知趋势又不至于输出太密。需要记录归档的时候我会把它接到 shell 循环里带上时间戳while true; do echo ---- $(date %F %T) ----; free -h; sleep 5; done free_trend.log如果觉得输出太宽可以试试free -w它会把 buffer 和 cache 单独拆开排查文件系统相关缓存问题时更清楚。还有两个容易踩的坑。第一个free 命令的默认单位在不同版本、不同发行版上不一样有的显示 KiB有的显示 GiB脚本化解析时建议用free -k或free -b固定单位否则线上和本地结果对比一个单位差异就可能把你带到沟里去。第二个老版本内核3.14 以前没有 available 列很多老旧环境的输出解读方式和新环境完全不同跨环境对比前先确认一下版本。再强调一次free 有天然短板它只告诉你“系统总共还剩多少内存”不告诉你“哪个进程在吃内存、吃得有多快”。所以 free 适合做第一眼判断不适合做根因定位。要看具体进程还得靠后面的 vmstat 和 sar 把问题一层层剥开。2. vmstat把内存状态变成速率盯住 si/so 的动态变化2.1 两段式输出的结构与第一行的陷阱vmstat 和 free 最大的不同是它把系统状态变成了“速率”。默认执行vmstat时输出分两段$ vmstat 1 3 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 655348 1203456 34860 68812124 0 0 3 18 120 130 14 6 80 0 0 1 0 655348 1203340 34860 68812124 0 0 0 0 125 135 15 7 78 0 0 1 0 655348 1203312 34860 68812124 0 0 0 0 131 140 16 7 77 0 0第一行比较特殊它显示的是自开机以来的平均值后续每一行才是采样时间窗内的瞬时值。很多人直接拿第一行当“当前状态”读这是新手最常犯的错误。看动态趋势必须跳过第一行从第二行开始。memory 区的 swpd、free、buff、cache 四项和 free 命令含义一致单位是 KB。不过对压测来说vmstat 里更值得盯的其实是另外几组swap 区的 si/so、io 区的 bi/bo、system 区的 in/cs、cpu 区的 wa/st。它们组合起来才能还原“内存压力”的完整现场。2.2 si/so 才是内存压力的体温计si 是 swap-in 的速率so 是 swap-out 的速率单位是 KB/s表示每秒从交换分区换入或换出多少数据。这两个数是我在内存分析里最先盯的指标正常情况下都应该趋近于 0偶尔出现一次两次小波动没大问题。一旦 si 和 so 开始持续非零基本可以断定物理内存已经撑不住了。打个比方swap 就像一个临时工仓库。内存里放不下的匿名页会被赶到这个仓库里等真正要访问的时候再从仓库搬回来。搬进搬出都需要时间和磁盘 IO而“搬”的过程就是 so 和 si。CPU 在等数据搬回来于是你会看到 cpu 列里的 wa 升高进程响应时间被拉长压测场景下直接表现就是 TPS 下跌、P95 变大。实际操作中判断内存压力的标准我一般这么看si/so 偶尔小幅度抖动可能只是瞬时波动继续观察。si/so 持续非零且数值在变大内存真实不足内核在积极换页。swpd 持续上涨且居高不下已有大量匿名页被换出后续访问这些页时还需要重新换入压力在累积。顺手补充一个底层对应关系vmstat 本身不凭空造数据它本质上是读取并计算/proc/meminfo和/proc/vmstat这两个虚拟文件。想深入排查时可以直接去/proc/vmstat里查 pgscan、pgsteal 这类字段它们比 vmstat 的摘要更接近内核回收机制的真实动作。2.3 队列、IO 与内存vmstat 里容易被忽略的交叉信号vmstat 的价值还在于它能把内存和 CPU、IO 之间的联动呈现出来。我遇到过这种场景free 显示 available 还行但 vmstat 的 r 列运行队列持续上涨wa 列也在抬头。如果只盯着内存看会觉得很莫名把几列连起来就明白了——内核正在回收内存回收过程要写回脏页于是 bi/bo 出现明显波动磁盘变忙任务排队r 列上升。这类联动经常是成串出现的si/so 大于 0 往往伴随 bi/bo 上浮因为换出脏页和读回换入页都要走磁盘wa 升高让任务执行变慢运行队列堆积运行队列堆积又让 CPU 的 sy 比例抬升。你在压测报告里看到的每一条曲线本质上都是这套联动关系的对外表现。压测期间我建议用vmstat 1 5开头先取 5 个一秒样本看波动幅度遇到可疑窗口再加长采样比如vmstat 1 60。关键不是采样多久而是采样窗口和压测脚本的业务阶段对齐压测是阶梯加压还是持续恒压峰值出现在第几分钟这些时间点如果不记录后面分析 vmstat 数据就只能靠猜。3. sar压测全程的历史回放能力是内存分析的底气3.1 sysstat 的采集链路与数据归档机制free 和 vmstat 的一个共同短板是“你盯着它的时候它才有数据”。可是内存异常往往不会按照你盯着的时间窗口出现——压测跑了两个小时到第三个小时才出问题或者凌晨批量任务把内存吃光第二天早上你才发现。这时候如果没有历史数据一切只能靠猜。sar 存在的意义就是解决这个问题。sar 是 sysstat 工具包里的核心命令。sysstat 装上之后会通过 cron 后台任务周期性调用 sadc 采集系统状态采集结果写入/var/log/sysstat/saXXXX 是当天日期部分发行版目录是/var/log/sa/。sar 命令本身做的事情其实就是读取并解析这些归档文件。所以哪怕你忘记了手动监控只要 sysstat 服务是开着的数据就在持续积累。默认采集间隔通常是 10 分钟一次看系统常识够了对性能测试来说太粗。压测场景我会把采集间隔改成 60 秒方法是修改/etc/cron.d/sysstat里 sa1 的调用参数# 默认 */10 * * * * root /usr/lib64/sa/sa1 1 1 # 改成每分钟 * * * * * root /usr/lib64/sa/sa1 1 1Debian/Ubuntu 的二进制路径可能是/usr/lib/sa/sa1原理一样。改完重启 crond 生效。另外sa 文件不会无限保留默认保留天数在/etc/sysconfig/sysstat部分发行版是/etc/sysstat/sysstat的 HISTORY 参数里长周期压测项目记得提前调大。3.2 内存相关三件套-r、-B、-Wsar -r是内存使用率的主视图重点看 %memused、kbmemfree、kbbuffers、kbcached还有一个容易被忽略的 kbcommit 和 %commit。kbcommit 对应/proc/meminfo里的 Committed_AS含义是当前所有进程已经向系统“承诺”的虚拟内存地址空间总和。它本质上是一个记账值系统根据它决定还能不能给新进程分配内存。如果 %commit 长期高企甚至超过 100%即使 free 显示 available 不错内存分配也会变得风险很高——默认 overcommit 策略下内核允许一定程度超卖但超卖严重时某些分配请求会失败或被 OOM Killer 优先清理。我压测一个 Java 服务时遇到过这类情况物理内存还剩一半%commit 已经爬到 170%新连接创建的线程栈在分配时就报错应用异常率陡增。sar -B看分页统计重点看 pgpgin/s、pgpgout/s、pgmajfault/s 和 vmeff%。pgmajfault 是主缺页次数意味着一个虚拟页不在物理内存里必须去磁盘拿数据或者重新建立映射。这个值正常运行时应该非常低。压测中如果 pgmajfault 持续明显上升说明内存可用页太少程序在不断踩缺页这是内存压力的典型信号。vmeff% 是页回收有效率低于 80% 说明内核在“低效地折腾”通常对应频繁回收但效果不佳的状态。sar -W是交换统计pswpin/s 表示每秒换入的页数pswpout/s 表示换出的页数。它和 vmstat 的 si/so 是同一件事的两个视角si/so 按 KB 算sar -W 按页数算。默认页大小通常 4KB换算关系一目了然。压测复盘里靠它确认 swap 活跃的持续时间比 vmstat 临时抓几个样本要可靠得多。3.3 用 sar 做压测窗口切片回放压测项目结束后最常用的操作是圈定时间窗口。比如压测从 14:00 开始15:30 出现波动15:40 恢复我可以一次命令把全过程的 %memused、%commit、pgmajfault、pswpout 都翻出来sar -r -f /var/log/sysstat/sa15 -s 14:00:00 -e 16:00:00 sar -B -f /var/log/sysstat/sa15 -s 14:00:00 -e 16:00:00 sar -W -f /var/log/sysstat/sa15 -s 14:00:00 -e 16:00:00拿到输出之后我会把时间轴对齐到 Jmeter 或 LoadRunner 的 TPS 曲线上观察内存指标和业务指标的变化顺序。是 TPS 先掉、内存后涨还是内存先涨、TPS 后掉这个先后顺序非常关键前者说明业务接入量变化是主因后者说明内存累积到某个阈值后触发了业务退化。到这里三个工具各自的定位已经比较清楚了工具定位时间维度主要回答的问题free系统快照当前瞬时现在还剩多少可分配内存vmstat实时抽样秒级动态当前内存与 CPU、IO、swap 的联动状态sar历史归档分钟级回放某一段压测窗口里到底发生了什么4. 一次真实内存异常的完整排查链路free、vmstat、sar 如何配合4.1 现象TPS 掉底free 却显示内存“很健康”之前有一个真实的压测场景特别适合拿来说明三个工具的联动方式。被测对象是一个电商后端的订单查询服务Jmeter 从 200 线程起压前 30 分钟 TPS 稳定在 1200 上下可用性很好。到第 40 分钟左右TPS 开始无规律下跌最差掉到 400然后自己又恢复反复震荡P95 明显拉长。第一反应自然是查系统资源。我敲了一下free -h$ free -h total used free shared buff/cache available Mem: 31Gi 18Gi 4.2Gi 1.2Gi 8.8Gi 12Gi Swap: 16Gi 2.3Gi 13Giavailable 还有 12Giswap 只用了 2.3Gi单看这一瞬间确实“健康”。但有两个异常点available 已经从压测刚开始时的 24Gi 降到了 12Giswap 也不是 0。单独一张快照没问题放到时间轴上就是“已经走完一半下坡路”。这就是 free 的局限——它只负责告诉你现在站在哪里不负责告诉你刚才发生了什么。4.2 排查链路free 快照 - vmstat 实时 - sar 回放我立即开了vmstat 1 5盯实时状态重点看 si/so 和 r、wa$ vmstat 1 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 8 0 2490504 3560012 80320 9231210 0 68 0 72 2100 4100 20 22 48 10 0 9 0 2490632 3559800 80320 9231210 0 72 0 80 2200 4300 20 23 45 12 0 7 0 2490656 3559710 80320 9231210 0 90 0 95 2100 4200 21 22 47 10 0so 持续非零说明内存在持续把匿名页换到 swapwa 有 10% 左右CPU 有一部分时间在等内存换页。单看 r 列 7-9 不算高但这是在 TPS 已经下跌的前提下——业务线程真正在跑 CPU 的时间变少了大量时间消耗在换页和等 IO 上。到这里问题方向基本确定物理内存不足swap 被迫频繁介入。接着用 sar 做全时段回放。把 14:00 到 16:00 的数据翻出来重点看 %commit 和 pgmajfault。结果是 kbcommit 从最初的 18Gi 一路爬到 27Gi%commit 从 110% 升到 170%pgmajfault 在 TPS 下跌前的 10 分钟就开始明显爬坡。这说明问题不是“某一瞬间内存不够”而是一个渐进累积过程虚拟内存承诺持续上涨物理内存回收压力逐步增大主缺页增加业务线程频繁被换页打断TPS 因此掉下来。再配合sar -B里的 pgpgin/s波动窗口平均接近 1800 页每秒约 7MB/s 的页输入速率和 wa 升高的现象完全对得上。整条链路闭环了。4.3 进入应用层堆外内存、本地缓存与 RSS到了这一步问题已经定性为“物理内存相对不足”但还没回答最关键的“为什么”是谁把内存吃掉的我在另一个终端用ps aux --sort-rss看了进程排行一个 Java 进程的 RSS 从压测初期的 6Gi 涨到了 12Gi。接着用jstat -gcutil看堆内指标GC 频率和暂停时间没有明显恶化说明问题很可能出在堆外——本地缓存、线程栈或者 JNI 分配的 Native 内存。翻代码后定位到一个“临时方案”为了性能把一批订单数据放进了 Guava Cachekey 按用户维度拆分。但每个用户的查询条件都不一样缓存几乎命中不上新对象反而不断被塞进去堆外内存被越顶越高。而且这段代码上线后没有加容量上限完全是无界缓存的用法。根因清楚了应用层无界缓存导致 RSS 持续增长最终把物理内存和 swap 一起拖垮。修复思路分两层。应用层给 Cache 加 maximumSize 和过期策略把 JVM 的-Xmx和容器上限对齐系统层在测试环境验证合适的 vm.swappiness 值这个场景我们希望优先使用 page cache 而不是激进换出匿名页所以从默认 60 调到 10具体数值看业务特性逐步试。改完重新压测free 的 available 稳定在 20Gi 上下vmstat 的 si/so 归零sar 回放全时段 %commit 不再单调上涨TPS 曲线恢复成 1200 的平直线。4.4 几个容易误判的侧面场景最后补充几个压测内存分析里特别容易翻车的侧面场景。第一个是 cgroup 限制环境。现在大量服务跑在容器里你敲 free 看到的是宿主机视图而容器实际能用的上限是 cgroup 限制值。两种视图差异可以很大宿主机 available 还剩 30Gi容器 limit 只有 4GiJava 堆直接超限被 OOMKilled。在容器环境分析内存第一件事是确认cat /sys/fs/cgroup/memory.max老版本是 memory.limit_in_bytes再看容器内进程实际占用主机的 free 输出反而是干扰项。第二个是内存回收导致的延迟毛刺。有时候 si/so 都是 0P99 还是时不时飙一下这就要怀疑内核的 direct reclaim直接回收。它在进程申请内存的路径上阻塞等待回收表现为一次短暂的停顿。可以通过/proc/vmstat里的 direct_reclaim_success 和相关字段确认。出现这种毛刺单纯加内存不一定有效要查是不是有进程一次性申请了大块内存或者透明大页导致分配路径变慢。第三个是 swappiness 的使用误区。很多人一看内存紧张就立刻把 vm.swappiness 改成 0认为“不用 swap 就安全”。实际不是这样swappiness0 只是让内核尽量不主动换出匿名页不代表禁止换出而且物理内存真的耗尽时禁用 swap 只会让内核更快走 OOM Kill 路线对在线业务杀伤更大。调优的前提是搞清楚瓶颈在哪而不是把参数当成开关乱拨。如果你现在只想给自己搭一套“先跑起来”的内存监控基线我直接把平时用的组合贴出来nohup vmstat 1 60 vmstat_trend.log 21 nohup bash -c while true; do echo ---- $(date %F %T) ----; free -h; sleep 60; done free_trend.log 21 sar -r -B -W -f /var/log/sysstat/sa$(date %d) sar_memory_summary.txt 21这套组合我已经用了很多年压测项目里十有八九的内存问题都能在半小时内定性free 负责告诉你“现在怎样”vmstat 负责告诉你“正在发生什么”sar 负责告诉你“到底从什么时候开始的”。三者合起来内存分析就不再是玄学。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

从零搭建Agent平台:Java Spring AI打造AI同事生产线 2026/9/26 19:16:48

从零搭建Agent平台:Java Spring AI打造AI同事生产线

上个月我把团队里散落的十几个Agent脚本收拢成一个统一的Agent平台时,有个同事看了一眼控制台,半开玩笑地说:"这不就是给AI建了个工厂,批量造同事嘛。" 我想了想,这个比喻真的很贴切。Agent平台本质上就是一…

阅读更多 →
鼎耀国际驻车柴暖用户力荐,安装便捷与稳定性能兼顾的优选方案 2026/9/26 19:16:48

鼎耀国际驻车柴暖用户力荐,安装便捷与稳定性能兼顾的优选方案

跑遍全国跑货运,冬天驻车过夜不敢熄车,既费油又提心吊胆;车自驾走南闯北,高原冰原想停下歇脚,取暖设备拖了后腿;做汽配改装接生意,卖出去的柴暖总是出问题,客户找上门售后难搞——不少从业者都在问&#xf…

阅读更多 →
ComfyUI短剧分镜生成:角色一致与空间连贯的工业级实践 2026/9/26 19:16:42

ComfyUI短剧分镜生成:角色一致与空间连贯的工业级实践

1. 这不是“AI画画”,而是短剧工业化生产的底层切口 最近在几个影视制作群和 indie 创作者圈子里,总有人发截图:一张张构图精准、光影统一、角色连贯的分镜图,标注着“镜头号|景别|运镜|情绪&am…

阅读更多 →
CRM系统落地实操复盘:从选型到团队推广的完整指南 2026/9/26 19:16:42

CRM系统落地实操复盘:从选型到团队推广的完整指南

做销售管理这些年,我越来越确信一件事:客户关系这种事,光靠脑袋和通讯录是管不住的。团队一旦超过五个人,报价、跟进、回款、售后就开始互相掺和,谁跟了哪个客户、上次聊到哪一步,全靠记忆和个人自觉&#…

阅读更多 →
自建轻量级CRM实战:从零部署到团队落地指南 2026/9/26 19:16:42

自建轻量级CRM实战:从零部署到团队落地指南

"DeskcommCRM"这个项目,说白了就是我自己搭的一套轻量级客户管理系统。平时团队用惯了各种免费SaaS CRM,功能看似齐全,可真用起来要么数据不在自己手里,要么免费版各种限制让人抓狂,要么员工用两天就嫌麻烦不…

阅读更多 →
自建CRM客户管理系统实战:从数据模型到永久在线部署 2026/9/26 19:16:42

自建CRM客户管理系统实战:从数据模型到永久在线部署

1. 为什么做 DeskcommCRM:企业自建客户系统的核心驱动力 1.1 现成工具的几个难言之隐 这几年我帮朋友公司做内部管理系统,听到最多的抱怨就是客户信息散落在各个销售的手机里、微信聊天记录里和一堆Excel表格中。销售离职时带走客户,新同事接…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉