在容器化运维中,理解内存指标是排查“OOMKiller(内存溢出)”和“内存泄漏”的关键。Linux 内核对内存的管理是非常精细的,Used RSS 和 Cached Memory 分别代表了内存的不同分配与利用状态。


1. 核心定义

Used RSS (Resident Set Size - 常驻内存集)

  • 定义:指进程当前实际占用的物理内存(RAM)。它包含了进程的代码段、数据段、堆栈、匿名内存映射(如变量存储)等。
  • 本质:这是内存的“核心占用”。如果容器被系统 Kill 掉(OOM),通常就是因为 RSS 占用了超过 memory.limit_in_bytes 的额度。它是不包含被交换到磁盘的内存,也不包含文件缓存。

Cached Memory (Page Cache - 页面缓存)

  • 定义:指内核为了提升 I/O 效率,将磁盘上的文件(如程序文件、日志文件、数据库数据)读取到内存中存储的副本。
  • 本质:这是内存的“利用潜力”。它属于“已用内存”,但属于可回收内存。当系统或容器内存紧张时,内核会优先释放这一部分空间以供进程使用。

2. 主要区别

特性Used RSSCached Memory
包含内容 进程私有内存(堆、栈、代码) 文件系统缓存(缓存磁盘数据)
回收难度 很难(进程主动释放,或被强制杀死) 很容易(内核自动回收)
性能影响 越低代表程序运行越困难 越高代表磁盘访问越快(性能越好)
内存限制 计入 OOM 统计,决定是否会被杀掉 计入容器内存使用量,但在压力下会被置换

3. 具体例子分析:一个 Python 脚本的运行

假设你在 Docker 容器内运行一个读取大文件并进行数据处理的 Python 脚本:

场景 1:脚本启动并读取 500MB 的 CSV 文件

  • 动作:内核将 CSV 文件内容加载到内存中以供脚本读取。
  • 指标变化:
    • Cached Memory:你会看到它瞬间增加了约 500MB。这是内核在为你做“缓存加速”,此时虽然内存总使用量上升了,但这是好事。
    • Used RSS:脚本本身的代码和解析 CSV 产生的 Python 对象占用了一部分物理内存(例如 100MB)。
  • 分析:此时容器的总内存使用(Working Set)是 600MB,但其中 500MB 是 Cached,随时可以被系统回收。

场景 2:脚本开始进行高密度的内存计算(内存泄漏)

  • 动作:脚本代码逻辑错误,导致不断向一个 list 中插入对象且不释放。
  • 指标变化:
    • Used RSS:会持续增加,从 100MB 涨到 500MB,再涨到 800MB...
    • Cached Memory:保持相对稳定,或者因为 RSS 挤占了内存而被迫被内核缓慢回收。
  • 分析:这是典型的内存泄漏。当 RSS 持续上涨并突破 memory.limit 时,Linux 内核会认为容器内存溢出,触发 OOMKiller 杀掉进程。

4. 运维中的监控逻辑

在监控面板(如 Grafana)中,你应该如何看待这两个指标?

  1. 观察 Cached Memory 是为了排除误报:
    如果你的容器内存报警了(比如达到了 limit 的 90%),不要慌。先看 RSS 和 Cached 的占比。如果 Cached 很大,说明内存紧张仅仅是因为内核缓存了太多文件,系统有足够的自动调节空间。

  2. 观察 RSS 是为了发现隐患:

    • 如果 RSS 持续线性增长(不回落),这几乎 100% 是代码存在内存泄漏。
    • 如果 RSS 激增(波峰),说明程序在处理某些大请求时瞬间需要大量计算内存,可能需要优化算法或增加容器内存限制。
  3. 理解“Working Set Memory”:
    在 Kubernetes 中,监控指标通常使用 container_memory_working_set_bytes,它大致等于 RSS + Active Cache。这是判断容器是否会 OOM 的最准确指标。如果这个值触碰 Limit,那么容器大概率要“挂”了。

总结:

  • RSS 是“身体的肌肉”,是程序运行的硬性需求。
  • Cache 是“桌上的工具”,平时放在桌上(内存)是为了用着方便,当没地方放东西(内存告急)时,工具随时可以被收进抽屉(磁盘)。
posted on 2026-07-07 16:05  卡米i  阅读(6)  评论(0)    收藏  举报