VPS内存占用越来越高,是缓存还是泄漏?用available、RSS和趋势判断

别看到used变大就清缓存;先确认可回收内存、业务延迟和哪个进程在持续增长
发布于
7

VPS内存占用越来越高,不应先下结论是“Linux缓存太多”或“程序泄漏”。used增加可能来自可回收页缓存、业务工作集扩大、容器限制、共享内存、内核Slab,也可能确实是进程长期不释放。判断关键是MemAvailable是否持续下降、Swap和延迟是否恶化,以及同一进程的内存是否在相近负载下单向增长

先读懂free输出,不要只盯used

free -h
grep -E 'MemTotal|MemAvailable|Cached|Buffers|Swap' /proc/meminfo
vmstat 1
指标 更接近的含义 怎样使用
MemAvailable 在不明显换页的情况下可供新任务使用的估算内存 比单看free或used更有参考价值
buff/cache 文件页缓存和部分内核缓存 其中部分可回收,不能全部视为浪费
Swap used 已有页面进入交换空间 需结合si/so和延迟判断当前压力
si/so vmstat中的换入、换出活动 持续活跃且服务变慢提示真实压力
RSS 进程当前驻留在内存中的页面 适合做趋势,不能简单相加共享页
PSS 按共享比例分摊后的进程内存 工具支持时更适合比较多进程总占用

如果used上升但MemAvailable稳定、没有持续换页、业务延迟正常,页缓存很可能在发挥作用。反过来,MemAvailable持续逼近低位且Swap频繁活动,就需要尽快定位增长来源。

缓存、工作集和泄漏的表现不一样

正常页缓存

读取网站文件、数据库文件、备份或镜像后,缓存可能增加。业务停止一段时间或出现新的内存需求时,系统可回收其中一部分。它往往与磁盘读取相关,不一定集中到某个应用RSS。

工作集自然增长

访问量、队列、连接数、数据库缓冲池或容器数量增加,会让应用真正需要更多内存。此时增长与业务规模相关,负载下降后可能部分回落,也可能保持在新的稳定平台。

疑似泄漏

在相似请求量和配置下,某个进程的RSS或PSS跨多个周期持续单向上升,重启后明显回落又以近似斜率增长,才更像泄漏。还应排除缓存上限、对象池、JIT、文件映射和垃圾回收策略。

按进程找增长,不要用一张top截图定案

ps -eo pid,ppid,user,rss,vsz,comm --sort=-rss | head -20
systemd-cgtop
journalctl -k --since "-2 hours" | grep -Ei 'oom|out of memory|killed process'

topps的一次快照只能告诉当前排序。更有效的是每隔固定时间记录PID、启动时间、RSS、请求量和容器状态,画出趋势。进程重启后PID会变化,应使用服务名、容器名或实例标识串联。

若系统安装了支持PSS的工具,可在权限允许时查看比例分摊;否则不要把多个进程RSS简单相加后与物理内存硬比,因为共享库和共享页可能被重复计算。

容器要看cgroup,不只看宿主机

cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.events
cat /sys/fs/cgroup/memory.stat

路径和字段取决于cgroup版本以及当前所在层级。容器平台通常也提供对应统计。重点核对内存上限、当前使用、匿名页、文件缓存和OOM事件。宿主机MemAvailable尚可,某个容器仍可能因自身上限被终止;容器显示较高,也可能包含该cgroup的文件缓存。

内核内存和临时文件也会增长

若普通进程RSS解释不了总占用,可继续检查:

  • Slab:大量文件、网络对象或内核子系统可能增加缓存,可用slabtop观察;
  • tmpfs:/tmp/dev/shm或容器内存卷会占用内存;
  • 共享内存:数据库、浏览器或多进程应用可能使用共享段;
  • 文件映射:内存映射文件会同时影响进程和页缓存观察;
  • 不可回收内核对象:需要结合内核版本、驱动和系统日志判断。

不要看到Slab大就直接执行来源不明的内核参数调整。先找出具体缓存类型、增长条件和是否可回收。

为什么定时drop_caches不是解决方案

页缓存用于减少磁盘读取,应用需要内存时内核会回收可回收页。定时清缓存可能让free数字短暂好看,却导致之后重新读取文件、增加IO和响应时间,也掩盖真正的应用增长。

受控诊断中如确需比较缓存前后,应先同步数据、选择维护窗口、记录IO与业务延迟,并明确回滚;生产环境不应把清缓存脚本当成常规运维。

一套低风险判断顺序

  1. 连续记录MemAvailable、Swap活动和业务延迟;
  2. 按服务或容器记录RSS/PSS与请求量趋势;
  3. 检查OOM、进程重启和容器memory.events;
  4. 区分匿名内存、文件缓存、tmpfs和Slab;
  5. 在测试环境用相同版本与负载复现;
  6. 确认泄漏后再做堆分析、升级、回滚或限制并发。

已经出现OOM或进程被杀,应结合极跃圈的VPS Swap与OOM判断方法确认压力和交换行为;若内存问题伴随磁盘等待,则还要同时检查Swap和日志写入带来的IO。

什么时候优化,什么时候扩容

明确某个缓存或缓冲池上限过高,可以按应用官方配置降低并验证命中率与延迟;确认版本泄漏时,优先升级到已修复版本、回滚近期变更或设置安全的临时重启策略。若正常业务工作集稳定超过物理内存,扩容比长期依赖Swap更合理。

任何调整都应保留基线:变更前后的MemAvailable、P95延迟、Swap活动、错误率和进程趋势。只有资源下降且业务没有退化,才能说明优化有效。

结论

VPS内存占用高的判断不能只看used。先用MemAvailable和Swap确认系统压力,再用RSS/PSS、cgroup、tmpfs与Slab定位增长来源;只有在相似负载下持续单向增长并能复现,才有较强理由怀疑内存泄漏。

常见问题(FAQ)

Linux的used内存很高就是内存泄漏吗?
不是。Linux会利用空闲内存作为页缓存,used升高可能是正常行为。应结合MemAvailable、Swap活动、业务延迟、OOM记录和进程RSS/PSS的时间趋势判断。
buff/cache可以直接手动清理吗?
通常不应把定期清缓存当作修复。可回收缓存会在应用需要内存时由内核管理,强行清理可能增加后续磁盘读取和延迟。只有明确诊断目的并理解影响时才做受控测试。
RSS持续增长就能证明程序泄漏吗?
RSS包含共享页和当前驻留内存,单点或短期增长不能直接证明泄漏。还需在相同负载下观察长期趋势、PSS、堆与映射、请求量、垃圾回收和版本变化。
容器内存高为什么宿主机看起来不一样?
容器受cgroup统计和限制影响,宿主机还包含页缓存、共享内存和其他进程。应同时查看宿主机与对应cgroup的memory.current、memory.stat、限制和OOM事件。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600