Linux 内存 available 很低但 free 很高是否正常现象?

文章导读
在 Linux 系统中,Free 内存高于 Available 内存通常不属于正常状态。正常情况下,Available 应包含 Free 以及可回收的缓存(Buff/Cache)。若出现 Available 异常偏低,往往与内核保留内存水位参数 vm.min_free_kbytes 设置过大有关。
📋 目录
  1. 诊断命令速查
  2. 原因分析
  3. 安全调整步骤
  4. 验证与监控
  5. 异常回滚方案
  6. 常见误区与风险
  7. 参考资料
A A

在 Linux 系统中,Free 内存高于 Available 内存通常不属于正常状态。正常情况下,Available 应包含 Free 以及可回收的缓存(Buff/Cache)。若出现 Available 异常偏低,往往与内核保留内存水位参数 vm.min_free_kbytes 设置过大有关。

核心结论:Free 显著高于 Available 属于异常现象,多由 vm.min_free_kbytes 参数过大导致内核保留了过多空闲内存。

  • 确认现象:对比 /proc/meminfoMemFreeMemAvailable 的差值。
  • 处理原则:切勿盲目设置固定值,需根据总内存大小评估,修改前务必备份原配置。
  • 验证标准:调整后 Available 回升,且系统无 OOM、网络丢包或卡顿现象。

诊断命令速查

执行以下命令快速定位内存状态及内核保留阈值:

# 查看内存概览,重点关注 available 与 free 的差值
free -h

# 查看内核保留内存阈值(单位 KB)
cat /proc/sys/vm/min_free_kbytes

# 查看总内存与详细字段,计算保留比例
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|MinFree"

原因分析

Linux 内存管理中,Free 代表完全未使用的物理内存,Available 是内核估算的应用程序可用内存(包含 Free 及部分可回收缓存)。

内核会保留一部分空闲内存作为紧急水位(Watermark),由 vm.min_free_kbytes 控制。这部分内存物理上空闲(计入 Free),但被内核锁定用于紧急场景(如网络包接收、内核栈扩展),不计入应用程序可用范围(不计入 Available)。

Linux 内存 available 很低但 free 很高是否正常现象?

若该参数被人为调大,会导致大量内存被“保留”而无法被业务使用,出现 Free 高但 Available 低的假性内存不足。

安全调整步骤

修改内核参数存在风险,请严格按照以下步骤操作,避免引发系统不稳定。

1. 备份当前配置

在修改前,务必记录当前值以便回滚:

# 保存当前值到临时文件
cat /proc/sys/vm/min_free_kbytes > /tmp/min_free_kbytes.bak

# 或记录到当前会话变量
ORIG_VAL=$(cat /proc/sys/vm/min_free_kbytes)
echo "Original value: $ORIG_VAL"

2. 评估合理范围

该参数没有绝对的官方固定值,通常由内核根据总内存自动计算。工程经验建议:

Linux 内存 available 很低但 free 很高是否正常现象?
  • 默认策略:若无特殊高并发网络需求,建议保持内核默认值。
  • 调整下限:对于内存大于 8GB 的服务器,建议不低于 65536 KB(64MB),过低可能导致高负载下网络包丢失或系统卡顿。
  • 参考比例:一般不超过总内存的 1%-3%。可通过以下命令估算总内存的 1% 作为参考下限:
# 计算总内存的 1% 作为参考值(单位 KB)
TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
SAFE_MIN=$((TOTAL_MEM / 100))
echo "Suggested minimum reference: $SAFE_MIN KB"

3. 临时调整测试

若确认当前值异常偏大(例如远超总内存的 3%),可尝试逐步调小观察效果,切勿一步到位:

# 示例:调整为参考值(请替换为实际计算出的安全数值)
# 假设计算出的安全值为 131072,切勿直接复制此数字
echo 131072 > /proc/sys/vm/min_free_kbytes

4. 永久生效配置

临时修改重启后失效。确认业务运行稳定后,再写入配置文件:

# 写入 sysctl 配置
echo "vm.min_free_kbytes = 131072" >> /etc/sysctl.conf

# 使配置生效(注意:这会重载所有 sysctl 参数,生产环境需谨慎)
sysctl -p

验证与监控

修改参数后,需持续观察系统状态以确保无副作用:

  1. 内存验证:再次执行 free -h,观察 available 列数值是否显著上升,且接近 free + buff/cache 的总和。
  2. 日志监控:使用 dmesg -w 或查看 /var/log/messages,确保没有出现 Out of memoryoom-killer 相关报错。
  3. 网络监控:观察网络接口丢包率(ifconfigip -s link),确保调整过低未导致网络包丢失。

异常回滚方案

若调整后出现系统卡顿、网络异常或业务报错,请立即恢复原值:

# 方法一:从备份文件恢复
if [ -f /tmp/min_free_kbytes.bak ]; then
  cat /tmp/min_free_kbytes.bak > /proc/sys/vm/min_free_kbytes
fi

# 方法二:从变量恢复(仅限当前会话未关闭)
echo $ORIG_VAL > /proc/sys/vm/min_free_kbytes

# 清理 sysctl.conf 中的修改
# 需手动编辑 /etc/sysctl.conf 删除对应行,然后执行 sysctl -p

常见误区与风险

  • 禁止设置过小:切勿将该值设置为极低数值(如几 KB),在高负载下会导致内核无法分配紧急内存,引发系统死锁或网络中断。
  • 避免频繁清理缓存:不要将 echo 3 > /proc/drop_caches 加入定时任务,这会降低文件访问性能且不能解决内存保留问题。
  • 大页内存影响:若启用了 HugePages,部分保留内存可能不会被计入 Available,需结合 /proc/meminfo 中的 HugePages 字段综合判断。
  • 云主机限制:部分云厂商实例可能限制该参数修改权限,若写入失败请检查权限或联系服务商。

参考资料

  • Linux Kernel Documentation - vm/min_free_kbytes
  • Red Hat Performance Tuning Guide - Memory
  • Kernel Source Code: mm/page_alloc.c (watermark calculation)