/proc/buddyinfo中每列数字表示对应阶数(order)的连续空闲页块数量,order=k对应2^k个页(默认4kb/页),如order=0为单页(4kb),order=10为1024页(4mb);每行对应一个numa节点和内存区域。

怎么看 /proc/buddyinfo 里的数字代表什么
/proc/buddyinfo 是内核暴露的 Buddy 分配器各阶空闲页块数量的快照,每行对应一个 NUMA 节点(如 Node 0),每列对应一个内存块阶数(0 到 10),数值单位是“页”(通常 4KB)。
例如这一行:Node 0, zone DMA 12 5 2 1 0 0 0 0 0 0 0,表示 DMA 区域中:1 个页的空闲块有 12 个,2 个页的有 5 个,4 个页的有 2 个……直到 2¹⁰ = 1024 个页(即 4MB)的空闲块为 0 个。
关键点在于:高阶(比如 order=9 或 10)数值越小,说明大块连续内存越稀缺;而低阶(order=0~3)数值持续偏高,往往意味着碎片正在积累。
为什么 free 显示 available 很高,但程序还是 OOM
这是外部碎片最典型的症状:系统总空闲页不少(MemAvailable 看起来健康),但缺乏足够大的连续物理页块来满足分配请求(比如驱动要 2MB 连续内存,或 kmalloc 请求高阶页),最终触发直接回收或 OOM killer。
常见诱因包括:
- 长时间运行后未释放的大页映射(如
hugetlb占用但未归还) - 频繁分配/释放中等大小内存(如 64KB~2MB),导致 buddy 系统无法合并成高阶块
- 内核模块(尤其是驱动)使用
__get_free_pages(GFP_KERNEL, order)但未严格控制order上限
此时看 /proc/buddyinfo,会发现 order=8 以上基本为 0,而 order=0~4 数值异常高——这不是内存不足,是“整块地都被切成碎砖头了”。
怎么算碎片指数(extfrag_index)并判断是否该做规整
内核用 extfrag_index 定量描述外部碎片程度,计算逻辑藏在 mm/page_alloc.c 中,但用户可通过以下方式间接验证:
执行:cat /proc/sys/vm/extfrag_threshold,默认值是 500。这个阈值决定了内核在分配失败时倾向走内存回收(direct reclaim)还是内存规整(compaction)路径。
当实际碎片指数趋近 0 → 表示几乎没空闲页,应优先回收(echo 1 > /proc/sys/vm/drop_caches 可临时缓解);
当趋近 1000 → 表示空闲页充足但极度离散,此时 drop_caches 没用,得靠 echo 1 > /proc/sys/vm/compact_memory 主动触发规整(注意:该操作有 CPU 开销,生产环境慎用)。
更稳妥的做法是监控 /proc/buddyinfo 中高阶页(order >= 8)是否长期为 0,并结合 dmesg | grep "page allocation failure" 确认是否已发生分配失败。
别只盯着 /proc/buddyinfo,这几个文件必须一起看
/proc/buddyinfo 是碎片的“X光片”,但单看它容易误判。必须交叉验证:
-
/proc/meminfo中的PageTables、KernelStack、CommitLimit和Committed_AS—— 排除内存过度承诺(overcommit)干扰 -
/sys/kernel/debug/page_owner(需开启CONFIG_PAGE_OWNER=y)—— 查哪类分配占用了大量中阶页(如 order=5~7) -
/proc/vmstat中的pgmajfault、pgpgin、pgpgout和pgmigrate_success—— 规整是否在后台静默生效
尤其注意:/proc/buddyinfo 不反映 ZONE_MOVABLE 的状态,如果系统启用了热插拔内存或 cgroup v2 的 memory.low,碎片可能集中在特定迁移类型区域,这时还得查 /proc/pagetypeinfo。











