Linux内存用满但不卡,因内核将空闲内存用于缓存(Buffers/Cached),真正关键指标是available列和swap活动;应用需合理配置内存上限并协同内核释放,swappiness应按场景调低,OOM Killer优先级需手动优化。

为什么 free -h 显示内存用满,但系统没卡?
Linux 的内存管理逻辑和直觉相反:它会尽可能把空闲内存用于缓存(Buffers / Cached),这不等于“被占用”。真正影响性能的是 available 列——它代表可立即分配给新进程的内存估算值。只要 available 不持续逼近 0,且 swap 使用量稳定(si/so 接近 0),就不必干预。
-
free -h中used高 ≠ 内存瓶颈;盯紧available和swap活动 -
cat /proc/meminfo | grep -E "MemAvailable|SwapTotal|SwapFree"可查更精确数值 - 频繁触发
kswapd0进程高 CPU 或pgmajfault持续上升,才是真实内存压力信号
应用层如何避免隐式内存浪费?
很多服务(如 Java、Node.js、PostgreSQL)默认配置会预留远超实际需要的内存,导致系统级可用内存被提前锁定。关键不是“调小”,而是让应用与内核协同释放。
- Java 应用:禁用
-XX:+UseContainerSupport(旧 JDK)或确保-XX:+UseCGroupMemoryLimitForHeap在容器中生效;堆上限建议设为物理内存的 50%~70%,留足页缓存空间 - PostgreSQL:降低
shared_buffers(通常 25% 物理内存已足够),提高effective_cache_size(告诉查询优化器“系统能缓存多少”,不影响实际分配) - Node.js:用
--max-old-space-size=限制 V8 堆,否则可能因 GC 延迟引发 OOM Killer 干预
什么时候该调 /proc/sys/vm/swappiness?
swappiness 控制内核倾向使用 swap 还是回收 page cache。默认值 60 对桌面合理,但对低延迟服务(数据库、实时 API)往往太激进。
- SSD 服务器:设为
1(仅当内存真正不足时才 swap),避免无谓 I/O 延迟 - 内存充足(>64GB)且运行内存敏感型服务:设为
0(禁止 swap,除非 OOM) - 注意:
0不等于“禁用 swap 分区”,只是禁止主动换出匿名页;仍需保留 swap 用于休眠或极端 OOM 回退 - 临时修改:
echo 1 > /proc/sys/vm/swappiness;永久生效写入/etc/sysctl.conf的vm.swappiness=1
OOM Killer 为什么总杀错进程?
内核根据 /proc/ 值决定 kill 优先级(范围 -1000 到 +1000),默认值基于内存消耗粗略估算,常误伤关键服务。
- 保护关键进程:启动后立刻设置
echo -900 > /proc/$(pgrep -f "my-critical-app")/oom_score_adj - 容器场景:Docker 用
--oom-score-adj参数,Kubernetes 用securityContext.oomScoreAdj - 避免依赖
oom_kill_disable(需 root + CAP_SYS_RESOURCE,且不推荐) - 查历史记录:
dmesg -T | grep -i "killed process",确认是否真因内存而非其他资源耗尽
内存优化真正的难点不在参数调整,而在于区分“内核在高效利用内存”和“应用在无意识吞噬内存”——前者不用动,后者不动就出事。











