2 GB 内存的服务器,内存到底被谁吃了

一台 2 核 2G 的小机器,跑几个常驻服务,free -h 一看 used 一个多 G,心里就开始慌:是不是要加内存了?

先别急。free 的几个数字里,最容易被误读的就是 used 和 buff/cache。

先看一份真实的输出

这是手上这台机器现在的样子:

               total        used        free      shared  buff/cache   available
Mem:           1.9Gi       1.0Gi       469Mi       1.6Mi       633Mi       931Mi
Swap:          1.9Gi       965Mi       1.0Gi

第一眼看上去:2G 内存用了 1G,只剩 469M,swap 还用了 965M——像是快撑不住了。

但真正该看的是最后一列 available = 931Mi。它才是“新起一个进程还能拿到多少”。

used 里包含了什么

free 的 used 大致是:

used = total - free - buff/cache

也就是说,buff/cache 那 633M 是被算在“没被用”里的。这部分是内核拿空闲内存做的磁盘缓存:读过的文件、写过的日志,都先放这儿,下次访问就不用再碰硬盘。

它不是被占用的内存。 一旦有进程需要,内核会立刻把这些缓存让出来。所以看到 buff/cache 很大,是好事,不是坏事。

available 就是内核估算的“可让出的量”:free + 大部分 buff/cache。它比 free 靠谱得多。

谁在真正占内存

free 只能告诉你总量,具体到进程得看 RSS:

ps -eo rss,comm --sort=-rss | head -10

rss 是常驻内存集,单位 KB。这台机器上排前几的是:

449928 hermes
126080 hermes
 54232 YDService
 45296 node
 34040 vaultwarden

两个 Hermes 进程加起来五百多兆,占了大头。剩下的代理、监控、密码库各几十兆,属于正常范围。

这里有个坑:RSS 会重复计算共享内存。多个进程 mmap 同一个库,每个进程的 RSS 都会把它算进去一遍,加起来会比实际用量大。所以把 RSS 直接相加,得到的数字偏高。

VSZ(虚拟内存)就更别看了,它包含还没真正分配的地址空间,动辄几个 G,没有参考价值。

swap 用了快 1G,是坏事吗

不一定。swap 里躺着的大多是很久没被访问的匿名页,比如启动完就再没用过的初始化数据。它们在 swap 里待着,反而给物理内存腾了地方。

真正要警惕的是这两个信号:

  • 持续 swap in/out:说明内存在频繁换进换出,性能会明显掉。
  • available 长期低于 100M:新进程一起来就可能触发 OOM。

看换页频率:

vmstat 1 5     # 看 si / so 两列,持续非 0 就要注意

这台机器 swap 占了 965M,但 si/so 基本是 0,说明只是“存着”,没有在折腾。可以接受。

内存都被谁拿走了:一张账

项目大约占用说明
内核和基础系统150–250 MBsystemd、sshd、日志、网络栈
两个 Hermes 进程550 MB 左右常驻,且不共享内存
代理与监控100 MB 左右云厂商的 agent、node 进程
密码库35 MB 左右Vaultwarden 很轻
buff/cache600 MB 左右可随时让出,不算压力

按这张账算,真正“被锁住”的大约 800–900 MB,剩下的是缓存和余量。2G 够用,但没有富余——再加一个吃 300M 的服务,就得开始换页了。

什么时候真的该加内存

三个信号,中一个就该考虑:

  1. available 常年低于总内存的 10%; 2 vmstat 里 si/so 持续不为 0,磁盘灯一直闪;
  2. dmesg 里出现 Out of memory: Killed process。

第三条最直接——OOM killer 已经开始随机杀进程了。它挑的通常是 RSS 最大的那个,所以表现出来的现象往往是“某个服务莫名其妙自己退了”。

dmesg -T | grep -i 'out of memory'

小机器上的几条习惯

  • 先算账再加服务。2G 的机器,每加一个常驻进程都要先估一下 RSS,别等 OOM 了再回头找。
  • 限制缓存。数据库、日志、容器都可能默认吃很多,能配上限就配上限。
  • 别关 swap。小内存机器关了 swap,等于把 OOM 的缓冲垫撤了。
  • 看 available,不看 free。free 小是正常的,Linux 会尽量把内存用起来。

回到开头那份输出:used 1.0G、buff/cache 633M、available 931M、swap 有存量但没在换页——这是一台“用得挺满,但还稳”的机器,不需要动它。