引言:当系统内存被"吃掉"的假象
"明明有 32GB 内存,为什么 free 命令显示只剩 2GB?系统是不是有内存泄漏?"
这是许多 Linux 运维工程师和开发者经常遇到的困惑。当你通过 free -h 命令查看系统内存时,发现 cached 占用了大量内存空间,第一反应可能是系统出现了问题。但实际上,这恰恰是 Linux 内核精心设计的内存管理策略在发挥作用。
本文将深入解析 Linux 系统中 cached 内存的本质、工作原理,以及在什么情况下需要进行干预和优化。
Linux 内存管理架构概览
内存分类体系
Linux 将物理内存划分为多个类别,每种类别都有其特定的用途:
graph TD
A[物理内存] --> B[Used 已使用]
A --> C[Free 空闲]
A --> D[Available 可用]
B --> E[Application 应用程序]
B --> F[Buffers 缓冲区]
B --> G[Cached 缓存]
G --> H[Page Cache 页缓存]
G --> I[Slab Cache 对象缓存]
G --> J[Tmpfs 临时文件系统]
关键概念解析
| 内存类型 | 说明 | 特点 |
|---|---|---|
| Buffers | 块设备的缓冲区 | 主要用于缓存块设备的元数据和正在进行的 I/O 操作 |
| Cached | 文件系统缓存 | 缓存文件内容,提高文件访问速度 |
| Free | 完全未使用的内存 | 可立即分配给任何进程 |
| Available | 可用内存 | 包括 Free + 可回收的 Buffers/Cached |
Cached 内存的工作原理
Page Cache 机制
Page Cache 是 Linux 内核中最重要的缓存机制之一。当应用程序读取文件时,内核会将文件内容缓存到内存中:
# 模拟 Page Cache 的工作流程
def read_file_with_cache(filename):
# 步骤1:检查 Page Cache
if filename in page_cache:
print(f"Cache Hit: 从内存读取 {filename}")
return page_cache[filename]
# 步骤2:Cache Miss,从磁盘读取
print(f"Cache Miss: 从磁盘读取 {filename}")
data = disk.read(filename)
# 步骤3:存入 Page Cache
if available_memory() > cache_threshold:
page_cache[filename] = data
print(f"已缓存 {filename} 到内存")
return data内存回收策略
Linux 内核采用 LRU(Least Recently Used)算法管理缓存:
// 内核内存回收的简化逻辑
struct page *reclaim_page_cache() {
struct page *page;
// 从 inactive list 开始回收
list_for_each_entry(page, &inactive_list, lru) {
if (page_is_clean(page)) {
// 干净页面可以直接回收
remove_from_cache(page);
return page;
} else if (page_is_dirty(page)) {
// 脏页需要先写回磁盘
writeback_page(page);
}
}
return NULL;
}诊断 Cached 内存占用
使用 free 命令
# 查看内存使用情况
$ free -h
total used free shared buff/cache available
Mem: 31Gi 8.2Gi 1.5Gi 256Mi 21Gi 22Gi
Swap: 8.0Gi 0.0Gi 8.0Gi解读要点:
buff/cache列显示了 Buffers 和 Cached 的总和available列才是真正可用的内存量- 不要只看
free列的数值
深入分析缓存组成
# 查看详细的内存信息
$ cat /proc/meminfo | grep -E "^(Cached|Buffers|SReclaimable|SUnreclaim)"
Cached: 21474836 kB
Buffers: 524288 kB
SReclaimable: 2097152 kB
SUnreclaim: 524288 kB
# 查看 slab 缓存详情
$ sudo slabtop -o | head -20
Active / Total Objects (% used) : 1847295 / 2134567 (86.5%)
Active / Total Slabs (% used) : 65432 / 65432 (100.0%)
Active / Total Caches (% used) : 152 / 217 (70.0%)
Active / Total Size (% used) : 512.3M / 598.7M (85.6%)监控缓存使用趋势
#!/bin/bash
# 实时监控缓存变化的脚本
while true; do
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
cached=$(grep "^Cached:" /proc/meminfo | awk '{print $2}')
buffers=$(grep "^Buffers:" /proc/meminfo | awk '{print $2}')
available=$(grep "^MemAvailable:" /proc/meminfo | awk '{print $2}')
echo "$timestamp | Cached: ${cached}KB | Buffers: ${buffers}KB | Available: ${available}KB"
sleep 5
done何时需要清理 Cached 内存
正常情况:不需要干预
在绝大多数情况下,高 cached 占用是正常且有益的: