为什么在Linux系统中,available会比free+buff/cache的总和少很多

在Linux系统中,available内存值小于free + buff/cache总和的现象源于内存管理的复杂机制。以下是核心原因及技术细节:


一、背景

1.现象

# 1.
free -h
              total        used        free      shared  buff/cache   available
Mem:          503Gi       475Gi       8.9Gi       605Mi        18Gi        13Gi
Swap:          63Gi        12Gi        51Gi
# 2.
grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached):' /proc/meminfo 
MemTotal:       527496080 kB
MemFree:         9574516 kB
MemAvailable:   14177788 kB
Buffers:             124 kB
Cached:         16713080 kB

  • MemAvailable:这是 Linux 内核提供的一种估算值,表示系统可用于启动新应用程序的内存量,它考虑了多种因素,包括可回收的缓存和缓冲区等,是一个综合反映系统可用内存状况的指标。
  • MemFree:表示系统中完全未被使用的内存量,这部分内存没有任何数据,可以直接分配给新的进程使用。
  • Buffers:用于存储磁盘块的缓冲区,这些缓冲区可以被快速回收用于其他用途,因为它们只是磁盘数据的临时副本。
  • Cached:表示被缓存的文件数据等,这些数据可以被快速访问,而且在需要内存时也可以被回收,因为文件数据可以从磁盘重新读取。

2./proc/meminfo说明

这段内容是关于Linux内核中/proc/meminfo文件的一个改进提议和实现说明。以下是对这段内容的详细解释:

2.1 背景问题

许多负载均衡和工作负载放置程序会检查/proc/meminfo文件来估算系统中有多少空闲内存可用。它们通常通过将“free”和“cached”相加来估算,这种方法在十年前是可行的,但如今几乎肯定不准确

2.2 原因分析

  • Cached内存的误区:Cached内存包括不能作为页面缓存释放的内存,例如共享内存段、tmpfs和ramfs。这些内存不能被释放用于其他用途。
  • 遗漏的可回收内存:Cached内存没有包括可回收的slab内存,这在有大量文件的空闲系统中可能占用了系统内存的很大一部分。

2.3 当前解决方案

目前,可以通过以下方式估算在不将系统推入交换空间(swap)的情况下,可用于新工作负载的内存量:

  • MemFree:当前空闲的内存量。
  • Active(file):活跃的文件页面。
  • Inactive(file):不活跃的文件页面。
  • SReclaimable:可回收的slab内存。
  • /proc/zoneinfo中的“low”水印。

2.4 问题和改进

  • 用户空间的困境:用户空间程序不应该被期望了解内核内部细节来估算空闲内存量。这使得用户空间程序难以准确估算可用内存。
  • 改进方案:在/proc/meminfo文件中直接提供这样的估算值会更加方便。如果未来情况发生变化,只需在一个地方进行修改。

2.5 实现细节

  • 新增字段:在/proc/meminfo中新增了MemAvailable字段,用于估算可用于启动新应用程序的内存量,而无需交换。
  • 估算方法
    • 考虑到系统需要一些页面缓存来正常运行,以及并非所有可回收slab内存都可以被回收(因为有些项正在使用中)。
    • 估算考虑了MemFreeSReclaimable、文件LRU列表的大小以及每个区域的低水印。
    • 估算值会根据系统的不同而有所变化。

2.6 总结

这段内容描述了在Linux内核中,为了更准确地估算系统可用内存,对/proc/meminfo文件进行了改进,新增了MemAvailable字段。这一改进使得用户空间程序能够更方便地获取系统可用内存的估算值,而无需深入了解内核内部细节。

二、为什么 MemAvailable 会低于 MemFree + Buffers + Cached

正常情况下,MemAvailable 的值应该接近 MemFree + Buffers + Cached,因为这些部分的内存都可以被系统回收用于新进程。然而,这段话中提到 MemAvailable 的值远低于这个总和,这说明系统中存在一些特殊情况,导致内核认为可用内存比实际的空闲内存、缓冲区和缓存的总和要少。可能的原因包括:

  • 内存碎片化:尽管有大量的空闲内存,但这些内存可能被分割成许多小块,无法满足新进程对大块连续内存的需求。
  • 内核预留内存:内核可能预留了一部分内存用于特定用途,这部分内存虽然未被使用,但也不能被分配给新进程。
  • 其他不可回收的内存占用:可能存在一些特殊的内存占用,如某些进程的匿名内存映射等,这些内存不能简单地被回收,从而影响了 MemAvailable 的估算。

1. 命令:slabtop

实时监控内核 ​slab 缓存使用情况的命令行工具,可帮助开发者和管理员分析内存分配状态、排查性能瓶颈。

Active / Total Objects (% used)    : 434059 / 438446 (99.0%)
Active / Total Slabs (% used)      : 23317 / 23318 (100.0%)
Active / Total Caches (% used)     : 104 / 200 (52.0%)
OBJS   ACTIVE  USE OBJ SIZE  SLABS CACHE SIZE NAME
120321  120297 99%    0.13K   4149    16596K dentry
64722   64605  99%    0.05K    966     3864K buffer_head
# 关键字段:
  # OBJS:总对象数
  # ACTIVE:活跃对象数
  # CACHE SIZE:缓存占用的物理内存量
  # NAME:缓存类型(如 dentry 为目录项缓存)

# 快速定位高负载缓存
slabtop -s c -d 5  # 每5秒按缓存大小排序

# 若发现特定缓存(如 dentry 或 inode_cache)对象数持续增长且未释放,可能指向内核模块或文件系统的内存泄漏。例如:
slabtop -s o | grep dentry  # 监控 dentry 缓存增长趋势

2. 命令:/proc/sys/vm/min_free_kbytes

强制 Linux 内核保留的最小空闲内存(单位:KB),用于保障系统内核关键操作(如网络、进程管理)的内存需求,避免因内存耗尽触发直接回收(direct reclaim)或 OOM Killer。

# 推荐值取以下两种计算的较大值:# NUMA 节点数 × 1GB​(如 4 NUMA 节点则为 4GB)# **总内存的 0.5%**​(如 512GB 内存则为 2.56GB)

# 计算推荐值并校验当前配置是否合理
TOTAL_MEMORY_KBYTES=$(free -k | awk '/Mem:/ {print $2}')
NUMA_NODE_COUNT=$(numactl --hardware | grep available: | awk '{print $2}')
NUMA_BASED=$((NUMA_NODE_COUNT * 1048576))  # 1GB per NUMA node
MEMORY_BASED=$((TOTAL_MEMORY_KBYTES / 200))  # 0.5% of total
RECOMMEND_VALUE=$((NUMA_BASED > MEMORY_BASED ? NUMA_BASED : MEMORY_BASED))

cat /proc/sys/vm/min_free_kbytes  # 当前生效值
grep vm.min_free_kbytes /etc/sysctl.conf  # 持久化配置

三、不可回收内存的扣除

1. 内核保留与锁定内存

系统内核自身运行需要保留部分内存(如内核数据结构、中断处理缓冲区),这些内存无法被回收。例如:

  • 低水位预留内存:为防止内存不足时关键操作阻塞,内核预留lowmem_reserve内存。
  • 临时锁定的页面:某些I/O操作(如DMA传输)会临时锁定内存页,导致缓存无法释放。

2. Slab缓存中的不可回收部分

Slab分配器用于管理内核对象缓存,其中SUnreclaim(如某些驱动模块的内存)无法被释放。例如,某服务器可能因Slab占用12G内存导致available显著减少。


四、缓冲/缓存的实际可回收性限制

1. Buffer与Cache的差异

  • Buffer(块设备缓存):直接读写磁盘块时产生的缓存(如/dev/sda1),通常较小且部分不可回收。
  • Cache(文件页缓存):大部分可回收,但某些场景(如正在写入的文件或内存映射文件)会被锁定。

2. 共享内存的占用

tmpfs等内存文件系统占用的内存属于Cache,但无对应磁盘文件,需通过Swap释放。若未配置Swap,则无法回收。


五、内存统计的估算特性

available是内核通过启发式算法估算的可用内存,而非精确值:

  • 估算依据:基于最近内存使用模式预测可回收量,而非简单累加free + buff/cache
  • 内核版本差异:3.14版本后引入available指标,老版本通过-/+ buffers/cache近似计算,两者均存在误差。

六、示例场景分析

假设某系统free=4GBbuff/cache=20GB,但available=18GB,可能因:

  • 内核保留内存占用2GB(如lowmem_reserve和Slab的SUnreclaim)。
  • 5GB的Cache被进程锁定(如数据库内存映射文件)。
  • tmpfs占用3GB且未配置Swap。

总结与建议

  1. 关注available而非freeavailable反映系统真实可用内存,而free仅是完全未使用的内存。
  2. 排查内存占用:通过/proc/meminfo查看SlabShmem等细节,或使用smem工具分析进程级内存分布。
  3. 优化方向
    • 减少tmpfs使用或配置Swap以释放共享内存。
    • 调整vm.swappiness降低缓存回收倾向,或手动释放非关键缓存(echo 3 > /proc/sys/vm/drop_caches)。

通过理解这些机制,可更精准评估Linux系统的内存健康状况,避免误判资源瓶颈。

你可能感兴趣的:(Linux,linux,运维,服务器)