网站运行一段时间后,监控面板显示内存占用达到 90%,是不是说明服务器配置不够了?
判断内存是否不足,需要结合可用内存、换页活动、进程占用以及故障日志。Linux 会使用内存缓存文件数据,部分缓存可以按需回收,因此,仅凭“已用百分比”或者“空闲内存很少”,无法确定是否需要扩容。
下面的排查方法适用于使用 systemd 的常见 Linux 服务器。命令在服务器的 SSH 终端中执行;Docker 部分需要在运行 Docker 的系统上执行。

一、先看 available,判断还有多少可用内存
执行:
free -h
重点关注以下字段:
| 字段 | 含义 | 判断方式 |
|---|---|---|
total | 系统可用的物理内存总量 | 用于了解容量 |
free | 当前完全未使用的内存 | 数值低不一定异常 |
buff/cache | 内核缓冲与缓存占用 | 其中部分可以回收 |
available | 预计无需换页即可供新应用使用的内存 | 评估内存余量的重要参考 |
Swap | 交换空间总量、已用量及空闲量 | 需要结合换页活动分析 |
available 是内核结合空闲内存、可回收缓存等因素估算出的值,不应简单理解为 free + buff/cache。
举例来说,一台服务器即使 free 只有 200MiB,如果 available 仍有数 GiB,且业务运行正常,就不能仅凭空闲内存较少判断它已经缺内存。
更值得关注的是:业务高峰时,可用内存是否持续下降,并且同时出现响应变慢、换页增加或者进程退出。
二、Swap 已用不代表正在频繁换页
执行:
vmstat 1 10
这条命令连续输出 10 次报告,更新间隔为 1 秒。第一行中的速率统计通常是自开机以来的平均值,判断当前情况主要看后续采样行。
重点观察:
swpd:已经使用的交换空间。si:每秒从交换空间换入内存的数据量。so:每秒从内存换出到交换空间的数据量。
如果 Swap 已使用一部分,但后续采样中 si、so 基本为零,只能说明当前没有明显的换页活动,不能据此认定服务器正在因 Swap 卡顿。
如果持续发生大量换入、换出,同时应用延迟升高,就需要进一步检查内存压力。反过来,没有配置 Swap 的服务器,即使已经缺内存,si 和 so 也可能始终为零。
支持 PSI 的系统,还可以查看:
cat /proc/pressure/memory
其中 some 表示至少部分任务因内存压力而停顿的时间比例,full 表示所有非空闲任务同时停顿的时间比例。avg10、avg60、avg300 分别对应不同时间窗口,这些是停顿时间比例,不是内存使用率。如果该文件不存在,可以跳过这一步。
三、找出内存占用较高的进程
执行:
ps -eo pid,comm,rss,%mem --sort=-rss | head -n 11
输出包含表头和 RSS 最大的前 10 个进程:
| 字段 | 含义 |
|---|---|
PID | 进程编号 |
COMMAND | 进程名称 |
RSS | 当前驻留在物理内存中的大小,单位为 KiB |
%MEM | RSS 占物理内存的比例 |
例如,RSS 为 1048576,约等于 1GiB。RSS 适合初步定位占用较大的进程,但包含共享内存,不能把所有进程的 RSS 直接相加,作为系统实际总占用。
找到进程后,要结合业务判断:
- 数据库占用较大,可以检查缓存配置和连接数量。
- 同类工作进程数量很多,可以检查并发配置。
- 在相似业务负载下,某个进程占用持续上涨,需要进一步排查缓存增长、任务积压或内存泄漏。
这里得到的是排查方向。单次排名靠前,并不能证明程序存在问题。
四、检查是否发生过 OOM
当内核无法回收足够内存以满足需要时,可能触发 OOM Killer,终止部分进程来释放资源。网站或数据库突然退出时,应检查故障时间附近的记录。
查看本次启动以来、最近 24 小时内的相关内核日志:
sudo journalctl -k -b --since "24 hours ago" --no-pager \
| grep -Ei 'out of memory|oom-kill|killed process'
如果出现匹配内容,需要记录发生时间、被终止的进程及上下文,而不是看到 Killed process 就直接升级服务器。
如果服务器已经重启,可以尝试查看上一次启动的内核日志:
sudo journalctl -k -b -1 --no-pager
能否查到上一次启动的信息,取决于历史日志是否保留。没有匹配结果,也不代表可以完全排除内存问题。
部分系统还启用了 systemd-oomd,它可能根据内存压力,在内核 OOM 发生前终止进程组。这种情况需要另外查看:
sudo journalctl -u systemd-oomd -b --since "24 hours ago" --no-pager
这一步适用于启用了该服务的系统。
五、使用 Docker 时,还要检查容器限额
服务器整体还有空闲内存,容器仍然可能因为达到自己的内存上限而触发 OOM。Linux 的 cgroup 内存限制可以独立于整台服务器的剩余容量生效。
先查看正在运行的容器:
sudo docker stats --no-stream
重点看 MEM USAGE / LIMIT,比较当前用量和限制。已经停止的容器不会通过这条命令返回实时统计;Linux 下 Docker CLI 的内存展示还会扣除部分缓存,因此不要直接与宿主系统的 free 数字逐项比较。
例如,服务器有 8GB 内存,但应用所在容器只允许使用 512MB,那么只升级服务器套餐,并不会自动改变这个容器的限制。
应先确认应用正常运行需要多少内存,再结合整机容量调整容器配置,同时给操作系统和其他服务保留余量。
六、根据排查结果决定是否扩容
下面是实际处理时可以参考的判断顺序:
| 观察到的情况 | 优先处理方向 |
|---|---|
| 缓存较多,可用内存充足,业务正常 | 持续观察业务高峰,无需为了降低显示占用而扩容 |
| 单个进程持续增长,业务负载没有同步增加 | 排查程序、缓存策略和任务积压 |
| 容器反复触及限额,整机仍有余量 | 检查容器内存限制和应用配置 |
| 正常业务高峰持续出现内存停顿、频繁换页 | 调整并发和资源分配,评估扩容或拆分服务 |
| 日志确认整机 OOM,且正常业务确实需要更多内存 | 优化后仍不足时,升级内存或迁移部分负载 |
也不建议把清理 drop_caches 当作日常“内存优化”。内核本身会按需回收缓存,强制清理可能增加后续重新读取数据的磁盘 I/O 和 CPU 开销。Linux 官方文档不建议在测试、调试场景之外常规使用它。
完成配置调整或扩容后,应在相似业务负载下重新观察可用内存、换页活动和响应时间。若使用 Docker,还需要再次核对容器限额,确认新增内存能够被需要它的应用使用。






