先用 free 看 available,别只看 used。再按缓存、进程、泄漏三类判断并留下证据。重启或清缓存之前,先确认服务器和进程归谁、能不能动。
要点速览
- 判断内存是否不够,看 available 和 swap 换页,不只看 used
- top 和 ps 以 RES/RSS 为准,VIRT/VSZ 不代表实际占用
- 按正常增长、突发峰值、疑似泄漏三类分别留时间点和进程证据
- 清缓存只让数字好看,重启会丢现场,动手前先确认归属
- 托管机器硬件内存告警走工单找机房,进程与参数由业务方决定
服务器内存占用高,先别急着重启。第一步用 free 看 available 一列,不要只看 used。Linux 会把空闲内存拿去做文件缓存,used 高、free 低往往是正常现象。available 持续走低、开始频繁用 swap,或者日志里出现 OOM 杀进程的记录,才说明内存真的不够。确认不够之后,再用 top、ps 找出是哪个进程占的,然后按正常增长、突发峰值、疑似泄漏三类分别记录证据。重启进程、清缓存、改内核参数之前,先确认这台服务器和这个进程归谁管、现在能不能动。这个顺序和站内 CPU 占用高的排查思路一样,只是内存有几处特有的坑,下面分四步讲。
第一步:分清「内存占用高」和「内存不足」
很多告警是按「已用内存占比」触发的。这个口径在 Linux 上容易误判:系统读写文件时会把内容留在内存里当缓存(page cache),下次读同一份文件就不用再走磁盘。有应用要用内存时,这部分缓存可以被回收。所以一台跑了几天的服务器,看上去内存「快满了」,多数时候只是缓存积累起来了,并不代表业务缺内存。
判断真正缺内存,通常看下面几个信号:
- available 持续下降:available 是内核估算出的、不靠 swap 还能给新程序用的内存,比 free 一列更接近「还剩多少能用」。
- swap 在持续换入换出:用了一点 swap 不一定有问题,关键看是否一直在进出。
- 出现 OOM 记录:内核日志里有 Out of memory 或 Killed process 字样,说明已经有进程因为内存不够被杀掉。
- 业务表现变差:响应变慢、偶发超时,而且时间上和前面几个信号对得上。
如果只有 used 高,上面几条一条都没出现,更合适的做法是调整告警口径,改为按 available 或按 OOM 事件告警,而不是去「处理」这台机器。
第二步:用 free、top、ps 看整体和进程,每条命令读哪几列
free -h:看整体
输出里分 Mem 和 Swap 两行。Mem 行先看 available,再看 buff/cache:buff/cache 大、available 也还宽裕,说明内存主要被缓存占着,是健康状态。shared 一列如果明显偏大,要留意 tmpfs 或共享内存段,这部分不能像普通缓存那样随手回收。Swap 行看 used 有没有在涨。可以隔一段时间执行一次,把几次结果放在一起对比,单看一次的参考价值有限。
vmstat 1:看是否在频繁换页
重点看 si、so 两列,分别是从 swap 换入和换出的量。偶尔有数字不必紧张,连续多行都不为零,说明内存压力已经影响到运行。
top:找出占用大的进程
进入 top 后按 M,按内存占用排序。读的时候分清三列:RES 是进程实际占用的物理内存,VIRT 是虚拟地址空间,通常远大于实际占用,不能拿来判断谁吃内存;SHR 是可共享部分,多个进程共用的库会重复计入。%MEM 是 RES 占总内存的比例。
ps:留下可对比的快照
ps aux --sort=-rss | head 按 RSS 从大到小列出进程。RSS 对应实际物理内存,VSZ 对应虚拟内存,同样以 RSS 为准。把输出连同时间一起存下来,后面判断趋势要用。
几个容易漏掉的地方
- 内核占用:所有进程的 RSS 加起来远小于已用内存时,可以看 /proc/meminfo 里的 Slab 一项,或用 slabtop,内核对象缓存有时会占不少。
- 容器限制:跑在容器里的进程受 cgroup 内存上限约束,宿主机看着还有余量,容器内照样可能被 OOM。要看的是容器自身的限制和用量。
- 运行时自带的堆:Java 这类应用会预先申请堆内存,RES 高可能只是堆的配置大,要结合应用自身的内存指标来看。
第三步:按正常增长、突发峰值、疑似泄漏三类判断,并记录证据
找到占内存的进程以后,不要马上下结论,先判断属于哪一类。不同类别处理方式不一样,需要的证据也不同。这里不给通用阈值,因为不同业务的合理水位差别很大,应以这台机器自己的历史数据作为参照。
正常增长
表现为占用随业务量上升,业务量回落后占用也跟着回落,或者涨到某个水平后趋于平稳。常见于缓存类服务预热、数据库缓冲池填满。要留的证据:占用曲线和业务量曲线(请求数、连接数)放在一起的对照。这类情况一般走扩容或调整配置,不属于故障。
突发峰值
某个时间点突然涨上去,可能伴随 OOM。常见原因有一次性大查询、批处理任务、导入导出、异常流量。要留的证据:精确的时间点、当时在跑的定时任务和批处理、当时的进程快照、内核日志里 OOM 记录的时间和被杀的进程名。用 dmesg -T 或 journalctl -k 可以查到带时间的内核日志。把这些时间对上,通常就能锁定是哪个任务触发的。
疑似泄漏
特征是业务量平稳甚至下降,某个进程的 RSS 仍在一个方向上慢慢涨,重启后回落,然后又开始涨。要留的证据:同一个进程在不同时间点的 RSS 记录(间隔固定,持续足够长)、进程启动时间、期间有没有发版或改配置。这份记录交给开发时,比一句「内存泄漏了」有用得多。注意,单凭几个小时的数据很难区分泄漏和缓慢预热,观察窗口要拉长一些。
三类情况都建议把证据写进同一份记录:时间点、主机、进程名和 PID、关键命令的原始输出、你的初步判断。后面不管是交给开发、交给业务负责人还是交给机房,都能直接用。
第四步:重启、清缓存、改参数之前,先确认归属
内存问题常见的三个「快速处理」,都有代价:
- 重启进程:内存会回落,但现场也没了。如果是疑似泄漏,重启前至少留一份进程快照;能做堆转储的,先跟开发确认要不要做。重启还会中断连接、丢掉未落盘的数据。
- 清缓存:向 drop_caches 写值可以让缓存立刻释放,但缓存本来就会按需回收,清掉之后系统要重新从磁盘读数据,短时间内磁盘压力反而会升高。它能让监控数字好看,解决不了真正缺内存的问题。
- 调内核参数:swappiness、overcommit 相关参数会影响整台机器上所有业务的行为,不该由排查的人临时决定。
所以动手前要先问清楚:这台服务器归哪个团队?这个进程的负责人是谁?当前是不是业务高峰,有没有维护窗口?操作需不需要走变更流程?这些问题有了答案,再决定动不动、怎么动。
托管场景下,哪些找业务负责人,哪些找机房
服务器放在机房托管时,软件层面的问题和硬件、现场的问题分属不同的人。大致可以这样分:
- 找业务负责人或开发:进程该不该重启、要不要做堆转储、配置和参数怎么改、是否需要扩容加内存。服务器里的系统和应用是你方的,这些决定归你方。
- 找机房:BMC 或系统日志里出现内存硬件告警(例如可纠正错误反复出现、内存条报错)、需要到场插拔或更换内存条、远程管理口也连不上需要现场看。这类事通过工单提交,写清机柜位置、设备标识、告警内容和期望的处理窗口。
具体哪些现场操作由机房代做、哪些需要你方到场,以签约时的服务约定为准,可参考站内《服务器托管故障谁负责?》一文。润迅在深圳运营前海云和田心两个数据中心,提供机柜托管和服务器托管,内存硬件告警这类需要到场核对的问题,会按工单流程和你方约定的窗口处理;进程和系统层面怎么改,仍由你方决定。
让 AI 帮忙整理输出,执行权留在人手里
内存排查的工作量,很多花在「读输出」上:free、vmstat、top、ps、内核日志几屏内容来回对照,还要和时间点、业务曲线对上。终端 AI 运维工具在这里能帮上忙。以润迅的 MaxTerm 为例(macOS / Windows,个人免费),它在终端里可以做这些事:
- 把几条命令的输出整理成一段摘要,标出 available 偏低、swap 在换页、某进程 RSS 持续增长这类可疑项;
- 从内核日志里找出 OOM 相关记录,按时间列出被杀的进程;
- 根据当前现象提示下一步可以看什么,比如建议检查容器限制或 Slab 占用。
边界需要说清楚:AI 做的是整理、标记和提示,命令是否执行由人确认。重启进程、清缓存、改内核参数这类会影响业务的操作,应当二次确认后再执行。哪些命令属于高风险、怎么分级,可以看《终端AI运维命令执行安全:哪些命令要人工确认?》。
行动建议:下次收到内存告警,按这个顺序走
- 先执行 free -h 和 vmstat 1,看 available 和 si/so,判断是缓存占用还是真的不够;
- 真的不够,再用 top 按 M 排序、ps 按 RSS 排序,找出占用大的进程,存下带时间的快照;
- 查内核日志确认有没有 OOM,对照业务量和定时任务,归入正常增长、突发峰值、疑似泄漏其中一类;
- 按类别补齐证据,写进一份记录;
- 动手前确认服务器和进程的负责人、维护窗口和变更要求;托管机器上出现硬件内存告警,走工单找机房;
- 告警长期只因缓存触发的,把告警口径改为 available 或 OOM 事件。
如果你经常需要在多台服务器之间做这类排查,可以试试用终端 AI 帮忙读输出、标重点。使用前先了解它对服务器数据怎么处理,可参考《AI 终端开始碰服务器之后,数据边界不能再含糊了》,再决定是否在生产环境里使用。
常见问题
Linux 服务器 free 显示内存快用完了,是不是要加内存?
不一定。Linux 会把空闲内存用作文件缓存,used 高、free 低常常是正常现象。先看 available 一列和 swap 是否在频繁换页,再查内核日志有没有 OOM 记录,都没有问题的话,通常不需要加内存。
内存占用高可以直接清缓存吗?
可以执行,但一般解决不了问题。缓存本来就会在应用需要时被回收,强行清掉后系统要重新从磁盘读数据,短时间磁盘压力会升高。真正缺内存时清缓存也无济于事,还是要找到占用的进程。
怎么判断是不是内存泄漏?
看同一进程的 RSS 在业务量平稳时是否仍单向缓慢上涨,重启后回落、之后又继续涨。需要按固定间隔记录较长时间,并核对期间有无发版或改配置,几个小时的数据很难和缓慢预热区分开。
托管的服务器内存出问题,该找机房还是自己处理?
进程重启、参数调整、扩容等系统和应用层面的决定由你方业务负责人做。BMC 或日志里出现内存硬件告警、需要到场更换内存条时,通过工单找机房,具体分工以签约时的服务约定为准。