直接答案:云服务器提示内存不足时,先看 MemAvailable、Swap 活动、进程实际占用和内核 OOM 记录,不要只盯着 used,也不要执行来源不明的“释放缓存”命令。Linux 会主动利用空闲内存做页缓存,这部分通常可在应用需要时回收;真正危险的是可用内存持续接近零、频繁换页、延迟上升,或者内核已经杀掉进程。
处理顺序应是:保留现场 → 判断是容量不足、泄漏、瞬时任务还是配置过量 → 先保护业务写入 → 限制或重启已确认的单个服务 → 修正进程和缓存预算 → 再决定加 Swap、升配或拆分。重启整机只会暂时清空内存,无法解释为什么它会再次耗尽。
先读懂四组内存指标
| 指标 | 应怎样理解 | 需要警惕的组合 |
|---|---|---|
MemAvailable |
内核估算应用仍可使用的内存,比 free 更有意义 |
持续下降且业务延迟上升 |
buff/cache |
文件与内核缓存,通常可回收一部分 | 不能单独当作泄漏证据 |
| RSS/PSS | 进程驻留内存;PSS 更适合分摊共享页 | 单进程或同类进程持续增长 |
| Swap in/out | 内存页在磁盘与 RAM 间交换 | 持续换入换出并伴随 IO 和延迟 |
先执行 free -h、cat /proc/meminfo,再用 ps -eo pid,user,rss,vsz,stat,lstart,cmd --sort=-rss 和 pidstat -r 1 10 连续采样。容器环境还要核对容器限制与宿主机总量;容器内看到的“剩余内存”不一定代表宿主机还有相同余量。
怎样确认是否发生过 OOM
内核在无法满足内存分配时,可能选择进程终止。用 journalctl -k 或发行版相应内核日志搜索 oom、Out of memory、Killed process。应记录被杀 PID、进程名、时间、cgroup/容器、总内存与触发前业务事件。
只看到应用“突然退出”不能自动认定 OOM;也可能是守护进程重启、段错误、人工操作或健康检查失败。反过来,服务很快被自动拉起也不代表没有数据影响,队列、上传、订单和数据库事务都要单独核对。
内存去哪了:按来源定位
应用进程或 Worker 过多
PHP-FPM、Gunicorn、Java、Node.js 和队列 Worker 常按“单进程峰值 × 最大并发”消耗内存。配置 50 个 Worker 不代表机器能同时承受 50 个峰值请求。先测单进程在真实高峰下的 RSS,再乘最大并发并加系统余量。
数据库和缓存配置过大
MySQL Buffer Pool、每连接缓冲区、Redis maxmemory 都会与应用争夺内存。全局缓存不是唯一占用;每连接排序、临时表和线程栈会随并发增长。不要把数据库缓存直接设为物理内存的固定百分比而忽略同机应用。
内存泄漏或无上限队列
如果同一进程 RSS 随时间单向增长,业务量下降后也不回落,应按版本、接口和对象类型查泄漏。无界任务队列、把整份文件读入内存、日志批量聚合也会表现相似。需要保留多时间点曲线,而不是只看故障后的单次 top。
突发任务与缓存重建
备份压缩、图片处理、依赖安装、搜索索引、报表导出会制造短时峰值。把任务移到低峰、限制并发和分块处理,通常比长期为一次任务购买大内存更合理。
一个可落地的容量预算
可用下面的采购公式做初算:
所需内存 = 操作系统与常驻服务 + 数据库全局缓存 + 单连接/单Worker峰值 × 最大并发 + 文件缓存与临时任务 + 故障余量
例如系统和守护进程 0.8GB,数据库常驻 1.2GB,6 个应用 Worker 每个峰值 220MB,备份任务峰值 0.6GB,再留 20%~30%余量,2GB 机器显然不足。这里的数值必须来自自己环境的采样,不能照搬他人的“2核4G能跑多少”。可同时参考一个云服务器可以放几个网站与配置选择指南。
Swap 能不能解决内存不足
Swap 是缓冲,不是与 RAM 等价的扩容。它可降低突发峰值直接触发 OOM 的概率,也能存放不活跃页;但持续把活跃工作集换到磁盘会造成明显延迟。数据库、实时接口和磁盘 IO 已紧张的机器,不应把“增加很大 Swap”当作长期方案。
启用前应确认磁盘空间、介质性能和加密要求;启用后观察 vmstat 1 的 si/so、IO 延迟和接口响应。若性能恶化,应按原配置回滚,而不是继续调高 Swap。不要删除正在使用的 Swap 文件,先按系统文档安全停用并确认可用内存。
应急止损顺序
- 暂停已确认的非核心批处理、备份或异常队列消费者。
- 对单个泄漏实例做平滑摘除并保存日志,不同时重启所有副本。
- 降低应用并发或连接池上限,避免进程数量继续膨胀。
- 启用已有缓存或限流,降低动态请求进入量。
- 只在根因和数据安全边界明确后,重启单项服务或临时升配。
如果内存长期不足且业务确实增长,可查看美国弹性云服务器或美国轻量云的实时可选配置。升配后仍要保留原问题的监控,否则泄漏只会在更晚时间再次发生。
修复后的验收
至少跨过一个真实高峰或等价压测周期,确认 MemAvailable 不再单向下降、没有新的 OOM、Swap 不持续大量换入换出、应用延迟和 5xx 正常、队列能消化、数据库连接稳定。再做一次服务重启与备份任务测试,确认容量预算同时覆盖日常和维护场景。告警应关注可用内存、OOM、换页和业务表现,而不是仅以 used > 90% 触发。可结合云服务器监控告警指南设置多条件告警。
常见问题
free 很少就是内存不足吗?
不一定。Linux 会用空闲内存做缓存,优先看 MemAvailable、换页、延迟和 OOM 证据。
可以执行 drop_caches 释放内存吗?
它会丢弃可回收缓存并增加后续磁盘读取,通常不是业务内存泄漏的修复方法。除非在明确的测试场景理解其影响,否则不应作为日常“优化”。
增加 Swap 后为什么网站更慢?
说明活跃内存页可能在磁盘与内存之间来回交换。Swap 延缓 OOM,但磁盘延迟远高于 RAM,应减少工作集或增加真实内存。
重启 PHP 或 Java 后恢复,能说明问题解决了吗?
不能。它只证明进程占用被清空。需要继续观察同版本、同流量下的增长曲线,并找到泄漏、并发或缓存配置根因。
OOM 一定会杀占用最大的进程吗?
不一定。内核会结合占用、上下文和 oom_score_adj 等因素选择目标,日志中的被杀进程才是当前事件证据。