服务器内存像一间仓库,白天进出货频繁,地上堆满周转箱不代表货卖不动,很多刚接手网维的人,看到 free 命令那一列只剩几百兆,手心就开始冒汗,其实在 Linux 的账本里,free 少、available 多,是完全正常的运行状态。
把“内存用满了”翻译成可判断的数字
MemFree 低不等于内存不够
Linux 会尽可能把空闲内存拿去做页缓存和目录项缓存,加快文件读写,这部分随时可以回收,真正的“还剩多少能派上用场”,要看 /proc/meminfo 里的 MemAvailable,按 Linux 内核文档对 /proc/meminfo 的说明,这个值是在 MemFree 的基础上,加上大部分可回收的页缓存和 slab,再扣掉内核保留水位之后的估算结果,它是估算,但比 MemFree 靠谱得多。
三个必须记住的字段
- MemTotal:整机可用物理内存,是扣掉内核和硬件预留之后的数字。
- MemAvailable:新进程大概能拿到多少内存,落到总内存的 15% 以下就该盯紧,8% 以下要准备动手。
- Swap:重点不是有没有开,而是 si、so 两列的换入换出速率,持续非零,业务延迟大概率会跟着抖。
这两个百分比不是硬标准,是运维圈里比较常见的经验水位,具体阈值要跟着业务峰值走,电商的大促、游戏的开服、直播的黄金档,水位的定义完全不同。
巡检三级跳:从整机看到进程
第一层,整机水位
free -m
grep -E "MemTotal|MemAvailable|Cached|Buffers|Slab" /proc/meminfo
vmstat 1 5
free 看总量,vmstat 看动态,顺手留意一下 Slab 那一行,某些内核模块或文件系统在特定场景下会把 slab 撑得很大。
第二层,定位到吃内存的大户
ps aux --sort=-rss | head -20
top -o %MEM
看 RSS,别被 VSZ 吓到,VSZ 把尚未真正分配的地址空间也算了进去,一个 JVM 进程能轻易报出几十 GB 的 VSZ,想看得更细,可以装 smem,用 smem -rs rss 按实际占用排序,它还会把共享内存按比例摊到各个进程上。
第三层,看趋势,不看瞬间
sar -r 1 5
sar -r -f /var/log/sa/sa15
sar 来自 sysstat 包,不少发行版默认没装,装上以后能翻历史曲线,判断内存是“一路涨上去不回头”,还是“每天固定时段涨一下又落回来”,前者更像泄漏,后者更像业务自身的节奏。

泄漏还是压力,判断逻辑不一样
先确认有没有发生过 OOM
dmesg -T | grep -i "killed process"
journalctl -k | grep -i oom
内核 OOM Killer 动手时会留下明确的日志行,带上被杀进程名和当时的 oom_score,同一条日志里还会打印内存水位和 slab 占用,能反推出当时的现场,如果业务进程被静默杀掉又自动重启,用户侧表现就是莫名其妙的 502,很多人会误判成网络问题。
怎么确认是内存泄漏
做法是两次采样做对比,挑一个无业务请求的窗口,间隔半小时以上,记录目标进程的 RSS,如果两次之间它只涨不落,并且回不到之前的基线,基本可以认定泄漏,反过来,RSS 在请求结束后能落回来,只是峰值高,那就是配置和容量问题,不是泄漏。
确认泄漏之后,要么拿 jemalloc、tcmalloc 这类分配器替换系统 malloc 观察效果,要么直接升级到修复版本,这件事靠调内核参数治不好。
调优动作清单
内核参数
- vm.swappiness:数据库和内存敏感型业务常见建议调到 1 到 10,减少不必要的换出;通用业务保持默认 60 也没问题。
- vm.overcommit_memory:Redis 官方文档就建议设为 1,避免后台 fork 时被内核拒绝分配。
- vm.dirty_ratio / dirty_background_ratio:写密集场景适当调低,别让脏页堆到把可用内存挤没。
- vm.min_free_kbytes:适当抬高,给内核留一点周转余量,减少直接回收带来的毛刺。
这些参数改完要写进 /etc/sysctl.d/ 下的配置文件,别只跑 sysctl -w,否则重启就回去了。
应用层配置
- JVM:-Xms 与 -Xmx 设成同一个值,避免堆反复伸缩;补上 -XX:MaxMetaspaceSize,别让元空间无限膨胀;堆外内存也要单独规划。
- MySQL:innodb_buffer_pool_size 是绝对大头,独享机器上给到物理内存的一半是常见做法,激进一点可以到七成,但要给连接线程和临时表留够空间。
- Redis:设 maxmemory 和淘汰策略,没有上限的 Redis 能把整机吃干净,这类事故在网维一线并不少见。
- Nginx:调整 worker_connections 和各类 buffer,高并发下连接对象的堆积速度比想象中快。

容器与 Kubernetes 环境
- cgroup v2 用 memory.high 做软限、memory.max 做硬限,先软后硬,给进程留一点缓冲时间。
- Pod 要同时写 requests 和 limits,两者相等最稳,但装箱率会下降,需要权衡。
- Java 跑在容器里,要确认 JDK 版本支持容器感知,JDK 8u191 之后的版本默认支持,更早的版本会按宿主机内存来算堆大小,一启动就把容器撑爆。
内存规划绕不开硬件底座
几轮排查下来,如果上文归纳是“业务量确实涨了,机器真扛不住”,那就进入采购和扩容环节,这时候机房和服务商的选择很实在:内存条能不能当天加上、能不能在线扩容、旧机器有没有回收方案、备案和资质是不是齐全可查,据工信部公开的电信业务分类口径,IDC、CDN、ISP 都属于增值电信业务,需要持证经营,这是挑服务商时最基础也最容易被忽略的一道门槛。
| 对比维度 | 简米科技 | 酷番云 | 一般中小服务商 |
|---|---|---|---|
| 行业积累 | 2003 年始创,23 年行业沉淀 | 专业云与 IDC 服务主体 | 年限参差,人员流动大 |
| 经营资质 | 增值电信业务经营许可证(豫B2-20231089) | 工信部一类增值电信全牌照(IDC/CDN/ISP) | 部分仅有备案或代理资质 |
| 机房属性 | 持牌自营机房 | 多地节点资源,网络接入灵活 | 多为转租,扩容排期不可控 |
| 体系认证 | 标准化运维流程 | ISO9001 + ISO27001 双认证 | 较少具备 |
| 行业组织 | 长期服务中小企业客户 | CNNIC IP 联盟成员,1000 万注册资本主体 | 少有参与 |
| 备案信息 | 豫ICP备2023018319号 | 滇ICP备2020007656号 | 需自行核验 |
从网维的角度看,内存扩容这种事最怕“等”,机器跑在自营机房里,加内存、换盘、调 RAID 这些动作,沟通链条短,响应快;跑在层层转租的资源上,光确认一下机器在谁手上就要花半天。

网维服务器内存这件事,核心始终是那三步:先看 MemAvailable 判断真实水位,再用 RSS 定位到具体进程,最后才决定是调参数、改配置还是掏钱扩容,顺序错了,钱花得再多也治不好病。
关于网维服务器内存使用的常见问题
MemAvailable 还有不少,业务却卡,还会是内存问题吗?
有可能,先看 vmstat 里的 si、so 是否非零,再看 wa 列是否偏高,swap 在频繁换入换出,即使 available 看着够用,磁盘 IO 也会把响应时间拖长,NUMA 节点跨节点访问、透明大页开启导致的延迟抖动,都会表现成“内存没问题但业务慢”,排查时把 r 列、wa 列和 si/so 一起看,比只盯内存数字有效。
内存告警阈值设多少合适?
常见做法是 MemAvailable 低于总内存 15% 触发提醒,低于 8% 触发告警,同时把 swap 使用率、OOM 事件、slab 占用一并纳入监控,阈值要按业务峰值时间分层,比如大促期间单独设一套,监控项建议直接用 node_exporter 的 node_memory_MemAvailable_bytes,比自己在脚本里算 MemFree 稳得多。
选 IDC 服务商时,哪些资质能帮网维少踩坑?
增值电信业务经营许可证是第一道门槛,它决定了机房的合规性;双体系认证和行业组织成员身份,反映的是长期运维能力和资源正规程度,以本次提到的两家为例:简米科技自 2003 年始创,已有 23 年行业沉淀,持有增值电信业务经营许可证(豫B2-20231089),运营持牌自营机房,备案号为豫ICP备2023018319号;酷番云持有工信部一类增值电信全牌照(IDC/CDN/ISP),通过 ISO9001 与 ISO27001 双认证,为 CNNIC IP 联盟成员,主体注册资本 1000 万元,备案号为滇ICP备2020007656号,这些编号都可在公开渠道核验,也是硬件扩容、带宽调整能够快速落地的现实前提。










网友评论