本文档深入解读 /proc/meminfo 的输出信息,帮助理解 Linux 内核的内存管理机制。


1. 命令简介

什么是 /proc/meminfo?

/proc/meminfo 是 Linux 内核通过 proc 虚拟文件系统暴露的内存统计信息接口。它提供了系统内存使用情况的实时快照,是诊断内存问题的核心数据源。

cat /proc/meminfo

主要用途

用途 说明
内存监控 实时查看系统内存使用状态,判断是否存在内存不足
性能调优 分析缓存效率、Swap 使用率、大页配置等,优化系统性能
故障诊断 排查 OOM(内存溢出)、内存泄漏、异常换页等问题
容量规划 评估应用内存需求,制定扩容或优化方案
内核开发 理解内核内存管理机制,调试内存子系统

典型应用场景

  1. 服务器运维

    • 监控生产环境内存健康状态
    • 设置告警阈值(如 MemAvailable < 10%)
    • 分析内存使用趋势
  2. 应用性能优化

    • 评估应用的实际内存占用(AnonPages、Mapped)
    • 优化文件缓存策略(Cached、Buffers)
    • 调整 Swap 策略(swappiness 参数)
  3. 数据库/中间件调优

    • 配置大页(HugePages)提升性能
    • 使用 mlock 锁定关键数据避免换出
    • 监控共享内存使用(Shmem)
  4. 容器/虚拟化环境

    • 分析 CMA、Balloon 等虚拟化相关内存
    • 评估内存过度提交(Committed_AS)风险
    • 监控嵌套页表开销(SecPageTables)
  5. 嵌入式/IoT 开发

    • 在资源受限环境中精细管理内存
    • 优化内核内存占用(Slab、KernelStack)
    • 配置 Zswap 压缩换页

相关命令

# 实时监控内存变化
watch -n 1 cat /proc/meminfo

# 简化视图
free -h

# 内存统计 + 换页活动
vmstat 1

# 进程级内存分析
top -o %MEM
ps aux --sort=-%mem | head

# Slab 缓存详情
slabtop
cat /proc/slabinfo

2. 示例系统情况分析

基于 /proc/meminfo 输出,以下是当前系统的内存状态总览:

内存分布图

┌─────────────────────────────────────────────────────────────────────┐
│                    物理内存总量: 46.2 GB                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────┐  ┌──────────────────┐  │
│  │         文件缓存 (Cached)                │  │   匿名页          │  │
│  │            29.3 GB (63%)                │  │  24.5 GB (53%)   │  │
│  │         ████████████████████            │  │  ████████████    │  │
│  └─────────────────────────────────────────┘  └──────────────────┘  │
│                                                                     │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐  ┌───────────────┐  │
│  │ 空闲内存    │  │ 内核 Slab   │  │ 页表/栈     │  │ 其他           │  │
│  │ 2.0 GB     │  │ 961 MB     │  │ 168 MB     │  │ ~300 MB       │  │
│  │ ██         │  │ █          │  │ ▪          │  │ ▪             │  │
│  └────────────┘  └────────────┘  └────────────┘  └───────────────┘  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                    Swap 空间: 2 GB                                   │
├─────────────────────────────────────────────────────────────────────┤
│  ████████████████████████████████████████░░░░░░░░░                  │
│  已使用: 1.6 GB (82%)                    空闲: 364 MB                 │
└─────────────────────────────────────────────────────────────────────┘

关键指标速览

指标 数值 占比/状态 评估
可用内存 31 GB 67% of Total ✅ 充足
文件缓存 29.3 GB 63% of Total ✅ 高效利用
匿名页 24.5 GB 53% of Total ℹ️ 正常
Swap 使用 1.6 GB 82% of Swap ⚠️ 偏高
内存提交 56.5 GB 225% of Limit ⚠️ 过度提交
脏页 348 KB < 0.01% ✅ I/O 正常
锁定内存 298 MB 0.6% of Total ℹ️ 正常

内存去向分析

内存使用分解 (近似值,部分有重叠):
─────────────────────────────────────────────────────────
用户进程匿名页   ████████████████████████  24.5 GB  (53%)
页面缓存 (文件)  ████████████████████████████  29.3 GB  (63%)
内核 Slab       █  961 MB   (2%)
页表            ▪  135 MB   (0.3%)
内核栈          ▪  33 MB    (0.07%)
共享内存        ▪  295 MB   (0.6%)
─────────────────────────────────────────────────────────
注: 页面缓存可被快速回收,因此可用内存远大于空闲内存

系统健康评估

维度 状态 说明
内存压力 🟢 低 MemAvailable 充足 (31GB),无需担心 OOM
缓存效率 🟢 优秀 大量文件缓存加速磁盘 I/O
Swap 健康 🟡 需关注 使用率高,需检查是否频繁换页
I/O 写回 🟢 正常 脏页极少,写回及时
内核内存 🟡 异常 SReclaimable=0 不寻常
碎片化 🟢 良好 大页映射占主导 (36.8GB 2M + 10GB 1G)

潜在风险点

  1. Swap 使用率 82%

    • 当前状态:1.6GB 已用 / 2GB 总量
    • 风险:若持续增长,可能导致换页风暴
    • 建议:运行 vmstat 1 观察 si/so 列
  2. 内存过度提交 (225%)

    • Committed_AS (56.5GB) 远超 CommitLimit (25.1GB)
    • 依赖内核启发式算法和 OOM Killer
    • 若所有进程同时使用已申请内存,可能触发 OOM
  3. SReclaimable = 0

    • 正常系统应有 dentry/inode 缓存可回收
    • 可能原因:特殊内核配置或统计异常
    • 建议:检查 /proc/slabinfo

3. 系统概览

指标 说明
总内存 48,467,840 kB (~46.2 GB) 系统物理内存总量
可用内存 32,528,360 kB (~31 GB) 可供新进程使用的内存
空闲内存 2,088,992 kB (~2 GB) 完全未使用的内存

4. 基础内存指标

4.1 核心内存统计

MemTotal:       48467840 kB    # 物理内存总量 (约 46.2 GB)
MemFree:         2088992 kB    # 完全空闲的内存 (约 2 GB)
MemAvailable:   32528360 kB    # 可用内存估算值 (约 31 GB)

解读:

  • MemTotal: 系统检测到的物理内存总量,不包括内核保留的部分
  • MemFree: 当前完全未被使用的物理内存。这个值通常较低,因为 Linux 会积极使用内存作为缓存
  • MemAvailable: 内核估算的可供新应用程序使用的内存量,包括可回收的缓存和缓冲区。这是判断系统内存是否充足的最重要指标

⚠️ 注意: MemFree 仅 2GB,但 MemAvailable 有 31GB。这说明系统内存状况良好,大量内存用于缓存可以快速回收。

4.2 缓冲区与缓存

Buffers:          504384 kB    # 块设备缓冲区 (约 492 MB)
Cached:         30731236 kB    # 页面缓存 (约 29.3 GB)

解读:

  • Buffers: 原始块设备 I/O 的缓冲区,主要用于文件系统元数据
  • Cached: 从磁盘读取的文件内容缓存(页面缓存),约 29.3GB,这是 MemAvailable 较高的主要原因

5. 活跃与非活跃内存

5.1 LRU 列表分类

Active:         27475616 kB    # 活跃内存 (约 26.2 GB)
Inactive:       15089816 kB    # 非活跃内存 (约 14.4 GB)

Linux 使用 LRU(最近最少使用)算法管理内存页面:

类型 说明
Active(anon) 1,013,352 kB 活跃匿名页(进程堆栈数据)
Inactive(anon) 10,636,036 kB 非活跃匿名页
Active(file) 26,462,264 kB 活跃文件页(文件缓存)
Inactive(file) 4,453,780 kB 非活跃文件页

解读:

  • 匿名页 (anon): 无文件后备的内存页,如进程的堆、栈、mmap 匿名映射
  • 文件页 (file): 有文件后备的内存页,即文件缓存
  • 活跃页: 最近被访问过的页面
  • 非活跃页: 较长时间未被访问的页面,内存回收优先淘汰这些页面

📊 当前状态: 文件缓存占主导(约 30GB),匿名页约 11.6GB,系统主要用于文件 I/O 密集型工作。

5.2 特殊锁定内存

Unevictable:      305148 kB    # 不可回收内存 (约 298 MB)
Mlocked:          305148 kB    # mlock() 锁定的内存

这些内存被锁定在 RAM 中,不会被换出到 swap:

  • 使用 mlock() 系统调用锁定
  • 常见于需要低延迟的应用(如数据库、实时系统)

6. 交换空间 (Swap)

SwapTotal:       2097148 kB    # Swap 总量 (2 GB)
SwapFree:         372576 kB    # 空闲 Swap (约 364 MB)
SwapCached:        90500 kB    # 已换出但仍在 RAM 中的缓存

解读:

  • Swap 使用量: 2097148 - 372576 = 1,724,572 kB (~1.6 GB)
  • Swap 使用率: 约 82.2%
  • SwapCached: 曾被换出但又被读回内存的页面,这部分同时存在于 RAM 和 Swap 中

⚠️ 警告: Swap 使用率较高(82%),建议监控系统是否频繁进行换入换出操作(可通过 vmstat 查看 si/so)。

6.1 Zswap 状态

Zswap:                 0 kB    # Zswap 压缩池大小
Zswapped:              0 kB    # 存储在 Zswap 中的数据量

Zswap 是一个压缩的内存缓存层,用于延迟或避免将页面写入实际 swap 设备。当前系统未启用或未使用 Zswap。


7. 匿名页与映射

AnonPages:      25724912 kB    # 匿名页总量 (约 24.5 GB)
Mapped:           797128 kB    # 映射到用户空间的文件页 (约 778 MB)
Shmem:            301736 kB    # 共享内存 (约 295 MB)

解读:

  • AnonPages: 所有匿名内存映射的总量,比 Active(anon) + Inactive(anon) 大,因为还包括其他类型
  • Mapped: 通过 mmap 映射到进程地址空间的文件页
  • Shmem: 包括 tmpfs、devtmpfs 和 POSIX 共享内存的使用量

8. 内核内存

8.1 Slab 分配器

Slab:             984088 kB    # Slab 总量 (约 961 MB)
SReclaimable:          0 kB    # 可回收 Slab
SUnreclaim:       984088 kB    # 不可回收 Slab
KReclaimable:          0 kB    # 可回收内核内存

解读:

  • Slab: 内核对象缓存,用于高效分配小型内核数据结构
  • SReclaimable = 0: 所有 Slab 内存都不可回收,这是异常情况

⚠️ 注意: 通常系统应有一定量的 SReclaimable(如 dentry 和 inode 缓存)。SReclaimable = 0 可能表示:

  • 内核配置特殊
  • 缓存压力导致已全部回收
  • 统计异常

8.2 内核栈与页表

KernelStack:       33520 kB    # 内核栈 (约 33 MB)
PageTables:       137980 kB    # 页表 (约 135 MB)
SecPageTables:      5552 kB    # 二级页表 (用于 KVM 等)

解读:

  • KernelStack: 每个线程都有独立的内核栈(通常 16KB),33MB 约对应 2100 个线程
  • PageTables: 用于虚拟地址到物理地址转换的页表结构
  • SecPageTables: 用于虚拟化的嵌套/扩展页表

9. 脏页与写回

Dirty:               348 kB    # 等待写回的脏页
Writeback:             0 kB    # 正在写回的页面
WritebackTmp:          0 kB    # FUSE 临时写回缓冲
NFS_Unstable:          0 kB    # NFS 不稳定页面(已废弃)
Bounce:                0 kB    # 弹跳缓冲区

解读:

  • Dirty: 已修改但尚未写回磁盘的页面,仅 348KB,说明系统 I/O 写入及时
  • Writeback: 当前正在进行磁盘写入的页面

✅ 脏页数量很低,说明 I/O 子系统工作正常。


10. 内存提交统计

CommitLimit:    26331068 kB    # 内存提交上限 (约 25.1 GB)
Committed_AS:   59234688 kB    # 已提交的地址空间 (约 56.5 GB)

解读:

  • CommitLimit = (SwapTotal + MemTotal × overcommit_ratio%)
  • Committed_AS: 所有进程申请的虚拟内存总量

⚠️ 过度提交: Committed_AS (56.5GB) > CommitLimit (25.1GB)

这说明系统处于内存过度提交状态。Linux 默认允许过度提交(vm.overcommit_memory=0),依靠 OOM Killer 在内存不足时终止进程。


11. Vmalloc 区域

VmallocTotal:   34359738367 kB  # Vmalloc 虚拟地址空间总量
VmallocUsed:       90528 kB     # 已使用的 Vmalloc (约 88 MB)
VmallocChunk:          0 kB     # 最大连续空闲块

解读:

  • VmallocTotal 是一个理论上限值(约 32TB),代表 vmalloc 可用的虚拟地址范围
  • 实际使用仅 88MB,主要用于内核模块和某些驱动

12. 大页 (HugePages)

12.1 传统大页

HugePages_Total:       0        # 预分配的大页数量
HugePages_Free:        0        # 空闲大页
HugePages_Rsvd:        0        # 已预留大页
HugePages_Surp:        0        # 超额大页
Hugepagesize:       2048 kB     # 大页大小 (2MB)
Hugetlb:               0 kB     # 大页总内存

当前系统未配置传统大页(HugePages)。

12.2 透明大页 (THP)

AnonHugePages:         0 kB     # 匿名透明大页
ShmemHugePages:        0 kB     # 共享内存透明大页
ShmemPmdMapped:        0 kB     # PMD 映射的共享内存大页
FileHugePages:     12288 kB     # 文件透明大页 (12 MB)
FilePmdMapped:         0 kB     # PMD 映射的文件大页

解读:

  • 系统启用了文件透明大页,使用了 12MB
  • 匿名透明大页未被使用,可能 THP 被禁用或碎片化严重

13. CMA (连续内存分配器)

CmaTotal:          32768 kB     # CMA 总量 (32 MB)
CmaFree:           27868 kB     # CMA 空闲 (约 27 MB)

解读:

  • CMA 为需要物理连续内存的设备(如 DMA、GPU)预留
  • 空闲率约 85%,状态良好

14. 直接映射统计

DirectMap4k:     3555224 kB     # 4KB 页映射 (约 3.4 GB)
DirectMap2M:    38555648 kB     # 2MB 大页映射 (约 36.8 GB)
DirectMap1G:    10485760 kB     # 1GB 超大页映射 (10 GB)

解读:

  • 这是内核直接映射区的页面大小分布
  • 大部分内存使用 2MB 和 1GB 大页映射,提高 TLB 效率

15. 其他字段

Percpu:            25632 kB     # Per-CPU 数据结构 (约 25 MB)
HardwareCorrupted:     0 kB     # 硬件损坏的内存
Unaccepted:            0 kB     # 未接受的内存 (用于保密计算)
Balloon:               0 kB     # 气球驱动使用的内存 (虚拟化)

16. 总结与建议

当前系统状态

方面 状态 说明
可用内存 ✅ 良好 31GB 可用,占总内存 67%
文件缓存 ✅ 高效 约 30GB 缓存加速文件访问
Swap 使用 ⚠️ 偏高 使用率 82%,需关注换页频率
内存提交 ⚠️ 过度提交 Committed > CommitLimit
Slab ⚠️ 异常 SReclaimable = 0 需要调查

优化建议

  1. 监控 Swap 活动:

    vmstat 1 10  # 观察 si/so 列
    
  2. 检查 SReclaimable 异常:

    cat /proc/slabinfo | head -20
    slabtop
    
  3. 如果 Swap 频繁使用,考虑:

    • 增加物理内存
    • 调整 vm.swappiness 参数
    • 检查是否有内存泄漏的进程
  4. 对于需要大页的应用(数据库、HPC):

    echo 1024 > /proc/sys/vm/nr_hugepages  # 预分配大页
    

17. 参考资料

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐