Linux PSI 怎样读取 memory pressure 的平均值
来源:17golang原创
时间:2026-10-24 22:29:42 128浏览 收藏
Linux PSI(Pressure Stall Information)读取 memory pressure 时,最直接的入口是 /proc/pressure/memory。其中 avg10、avg60、avg300 分别表示最近 10 秒、60 秒、300 秒窗口内,任务因内存资源不足而停顿的时间占比;它们不是内存使用率,也不是剩余内存百分比。
官方资料:https://www.kernel.org/doc/html/latest/accounting/psi.html
- 先读
some行判断是否有任务受到内存压力,再看full行判断是否出现所有非空闲任务同时停顿。 avg10/avg60/avg300用于观察短、中、长期趋势,total是从启动或统计重置以来累计的停顿微秒数。- 平均值升高只能说明等待压力增加,不能单独证明发生 OOM;还要对照回收、交换、容器配额和应用延迟。
最小读取方式是cat /proc/pressure/memory。把两行中的平均值记录成时间序列:短时avg10突然升高更像突发压力,avg60和avg300一起抬升才更接近持续性问题。
读取 memory PSI 文件中的平均值
先确认系统是否导出了 PSI 文件。内核关闭 PSI 或运行环境没有提供该接口时,不能通过改写解析脚本“补出”平均值;应该先确认内核配置、启动参数和容器可见的 procfs。
# 读取系统范围的内存压力统计;文件不存在时说明当前环境未提供该接口。
test -r /proc/pressure/memory && cat /proc/pressure/memory
# 只提取平均值,保留 some/full 标签,便于后续采集程序解析。
awk '/^(some|full) / {print $1, $2, $3, $4}' /proc/pressure/memory
典型格式如下,数值后带百分号语义但文本本身不包含百分号:
some avg10=0.42 avg60=0.18 avg300=0.06 total=1284500 full avg10=0.03 avg60=0.01 avg300=0.00 total=72400
some 表示至少有一个任务在等待内存资源;它更适合作为“系统是否已经出现可感知内存停顿”的第一观察面。读取时不要把 0.42 当作 0.42 字节或 42% 内存占用,它表示窗口内的停顿时间比例,数值单位是百分比。

区分 some、full 与 total 的含义
full 不是 some 的简单别名。它表示所有非空闲任务同时处于该资源停顿状态,通常意味着 CPU 没有可推进的工作,持续出现时要特别关注吞吐量和延迟。系统级 CPU 的 full 还有专门的语义边界,但 memory PSI 可以按文档读取这两类行。
total 使用微秒累计,从系统开始统计以来不断增加,适合发现“平均窗口没有明显抬头、但发生过短促尖峰”的情况。它不应和 avg300 直接相加或比较大小;一个是累计时间,一个是窗口比例。
| 字段 | 表示什么 | 适合回答的问题 |
|---|---|---|
some avg10 | 最近 10 秒内部分任务停顿占比 | 刚才是否出现突发内存压力 |
avg60/avg300 | 中期、长期停顿趋势 | 压力是否持续,而不是一次尖峰 |
full | 所有非空闲任务同时停顿占比 | 是否出现接近整体停摆的阶段 |
total | 累计停顿微秒数 | 窗口平均值之外是否发生过停顿 |
生产采集不要只抓一次。下面的示例每 5 秒读取一次,用于观察趋势;它是可执行的采集示例,不代表某台机器已经产生了这些数值。
# 每 5 秒采集一次 memory PSI;采集端按时间戳保存原始行。
while true; do
printf '%s ' "$(date -Is)"
# 只输出 some 行,快速观察部分任务的内存停顿趋势。
awk '/^some / {print}' /proc/pressure/memory
sleep 5
done

把平均值放回排查上下文
当 avg10 短时升高,先查看是否对应批处理、缓存突增或并发请求潮;当 avg60、avg300 也逐步升高,再检查内存回收、swap、容器限制和应用延迟。PSI 描述的是“因资源压力损失了多少工作时间”,并不直接告诉你是哪一个进程分配了最多内存。
如果只在容器或 cgroup 内做判断,还可以读取对应 cgroup v2 目录中的 memory.pressure。它与系统范围文件采用相同格式,但统计范围只覆盖该 cgroup 的任务。不要拿容器的平均值直接和整机值做同比,先确认统计边界一致。
# cgroup v2 示例:把路径替换成实际挂载点和目标 cgroup。 CGROUP=/sys/fs/cgroup/my-service if [ -r "$CGROUP/memory.pressure" ]; then # cgroup 文件格式与 /proc/pressure/memory 相同,但范围更窄。 cat "$CGROUP/memory.pressure" fi
建议保留一张最小排查记录:采集时间、统计范围、some/full 的三个平均值、total 增量、可用内存、swap 活动和业务延迟。这样才能判断压力是瞬时事件、长期趋势,还是只发生在某个容器。
常见问题
memory PSI 的 avg300 是过去 300 秒的普通算术平均吗?
它是内核维护的最近窗口压力比例,用来表达趋势;使用时应当把它当作 PSI 的窗口指标,不要自行把每秒样本做二次平均。
avg10 升高就代表马上要 OOM 吗?
不代表。它说明部分任务近期等待内存资源的时间增加,可能与回收或突发分配有关;是否 OOM 还要结合内存上限、回收结果、swap 和内核日志判断。
为什么 total 很大但 avg300 很低?
total 是长期累计值,而 avg300 只看最近五分钟。旧的压力事件会留在 total 中,近期恢复后窗口平均值仍可能很低。
总结
读取 Linux memory pressure 的关键不是只执行一次 cat,而是先认清字段:some 看部分任务是否停顿,full 看是否出现整体停顿,avg10/avg60/avg300 看不同时间尺度,total 看累计停顿。把这些值和统计范围、回收行为及业务延迟放在同一时间线上,平均值才有可操作的解释。
-
392 收藏
-
Golang · Go教程 | 3个月前 | channel · select · Context · Go教程 · 性能排查 · select channel context default time.Ticker Go教程 CPU飙高 for select459 收藏
-
395 收藏
-
Golang · Go教程 | 3个月前 | golang · Timer · 并发编程 · time.After · 性能排查 · time.After go timer Go 1.23 NewTimer Timer.Reset Timer.Stop403 收藏
-
425 收藏
-
162 收藏
-
128 收藏
-
273 收藏
-
175 收藏
-
372 收藏
-
418 收藏
-
486 收藏
-
167 收藏
-
448 收藏
-
333 收藏
-
117 收藏
-
125 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习