登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

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% 内存占用,它表示窗口内的停顿时间比例,数值单位是百分比。

Linux PSI memory 文件中 some 行的 avg10 avg60 avg300 与 total 关系说明图
图1:Linux PSI memory 平均值的静态结构说明图,展示三个时间窗口与累计停顿值的对应关系;不是运行截图。

区分 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
Linux PSI memory some full 和 total 的解释边界结构图
图2:memory PSI 的 some、full、total 解释边界说明图;它帮助区分部分任务停顿、整体停顿与累计时间,不是终端截图。

把平均值放回排查上下文

当 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 看累计停顿。把这些值和统计范围、回收行为及业务延迟放在同一时间线上,平均值才有可操作的解释。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>