在美国CN2 VPS上看到内存占用率贴着百分之八九十,很多人的第一反应是紧张。尤其是当你刚登录上去,还没跑什么像样的业务,free -h 的 used 列就已经很不好看,心里难免犯嘀咕:是不是买到超售机了,还是程序在偷偷漏内存?
先别急着下结论。Linux的内存管理和Windows是两套完全不同的逻辑,用Windows的任务管理器思维去看Linux的 free 输出,大概率会误判。CN2线路在这里只负责跨境数据包的路径质量,它跟VPS内部内存怎么花、花在哪里,没有直接关系。真正需要做的,是分清楚“内核拿空闲内存干了正事”和“某个进程在无节制地吞噬内存”之间的界限。
有三个信号,可以在不做复杂分析的情况下,把这两类情况分开。
信号一:看 available,而不是 used 或 free
这是最容易被忽略、也最基础的一步。很多人敲 free -h,目光直接落在第一行的 used 或者第二行的 free 上,然后根据那个数字下判断。这两个数字都会撒谎。
Linux内核有一个很朴素的设计意图:空闲的内存是浪费的内存。只要系统里有空闲的物理内存,内核就会拿它去缓存磁盘上的文件内容,也就是 page cache。这样下次读同一个文件时,直接从内存返回,不用再碰磁盘。你读写日志、加载程序库、访问网站文件,内核都在背后拿空闲内存做加速。当应用程序需要内存时,内核会立刻把一部分缓存回收掉让出来。
所以 free 列显示的数字很小,恰恰说明内核在积极干活。真正有参考价值的指标是 available,这一列是内核估算的“在不触发swap的前提下,还能分配给新进程的内存量”。如果 available 还有充足余量(比如总内存的百分之二三十以上),那么 used 高也好、buff/cache 大也好,系统实际上并不缺内存。
信号一的判断逻辑很简单:available 健康,内存占用高大概率是正常的缓存行为,不必恐慌。available 持续萎缩到很低水平,才有必要往下查。
信号二:buff/cache 能不能被回收
如果 available 确实偏低了,下一步要看的是:这些被占用的内存,到底是可回收的,还是动不了的。
free -h 里的 buff/cache 包含了文件页缓存和部分可回收的内核slab。这些东西在系统面临内存压力时,是可以被内核释放出来的。验证方法不复杂:先执行 sync 把脏页刷回磁盘,然后 echo 3 > /proc/sys/vm/drop_caches 手动清一次缓存,再立刻看 free -h。
如果 buff/cache 大幅下降、available 明显回升,而各个进程的 RES 基本没变,那之前的高占用就是缓存。缓存是正常现象,手动清它只是为了验证,生产环境不建议定期做这件事,因为清完缓存系统会立刻开始重新积累,还会带来短暂的I/O抖动。
如果清完缓存后,available 回升有限,或者过不了多久又掉回去,同时 buff/cache 并没有同步增长,那说明占着内存的东西不是缓存。这时候目光要转向进程侧。
信号三:盯住某一个进程的 RES,看趋势而不是看绝对值
这是区分正常高占用和内存泄漏最关键的一步。内存泄漏的定义不是“某个进程占了很多内存”,而是该进程的常驻内存随时间单调增长,且没有合理的回收机制。
数据库进程占几个G内存是正常的,Java应用堆内存开得大也是正常的,编译任务吃掉大量内存更是正常的。不正常的是:在一个负载大致稳定的时段里,某个进程的 RES 每隔一段时间就往上爬一截,爬上去就下不来,重启后暂时回落,然后继续爬。
操作上不需要复杂工具。用 ps aux --sort=-rss | head -20 先找出当前吃内存最多的几个进程,记下PID。然后隔半小时或一小时再跑一次,对比同一个PID的 RSS 数值。如果它在业务量没有明显变化的情况下持续增长,那就是需要警惕的信号。
更精细一点,可以看 /proc/<pid>/status 里的 VmRSS,或者用 smaps_rollup 看 Pss。RSS 会把共享库和共享内存重复计算,PSS 按比例分摊,对于多进程程序(比如PHP-FPM池、Node.js cluster)更能反映真实占用。不过对于“是不是在持续涨”这个判断,RSS 的趋势已经足够说明问题了。
还有一个辅助指标:如果 free 里 swap 的 used 在持续增长,同时 vmstat 1 的 si 和 so 列频繁出现非零值,说明物理内存确实不够用了,系统在拿磁盘当内存使。这种情况下,无论根因是泄漏还是单纯配置太小,都必须处理。
三个信号串起来怎么用?
把上面的逻辑收拢成一条判断路径:
先跑 free -h,看 available。如果 available 健康,到此为止,高占用是缓存,不用管。如果 available 低,做一次缓存回收验证:回收后 available 恢复明显、进程 RES 不变,是缓存;回收后 available 恢复有限,进入下一步。
盯进程 RES 趋势:如果某个进程在业务稳定时持续增长、重启才回落,那是泄漏或者至少是失控的缓存策略;如果没有单个进程的 RES 在涨,但 available 就是低,看 swap 和 si/so,可能是整体内存配置不够,或者内核slab在涨(slabtop 可以确认)。
相关内容
