numactl --hardware 是获取 NUMA 节点物理分布最准确的命令,它读取内核启动时解析的固件拓扑,显示节点数、各节点绑定的 CPU 列表、本地内存总量(kB)及节点间访问距离(对角线通常为10,≥25表明跨节点代价高),并需结合 dmesg | grep -i numa 确认 NUMA 是否真正启用。

用 numactl --hardware 看最准的 NUMA 节点物理分布
这是获取系统级物理内存拓扑的第一步,也是唯一能同时告诉你“哪些 CPU 绑定哪些内存块”的命令。它读取的是内核启动时从固件(BIOS/UEFI)解析出的硬件拓扑表,不是运行时调度结果。
输出中重点关注:
-
available: N nodes—— 实际被内核识别的 NUMA 节点数 -
node X cpus:—— 每个节点绑定的逻辑 CPU 列表(例如0-7) -
node X size:—— 该节点本地物理内存总量(单位 kB) -
node distances:—— 节点间访问延迟比值;对角线为基准(通常 10),非对角线若 ≥25 就说明跨节点访存代价显著
注意:如果 BIOS 中关闭了 NUMA,但 numactl --hardware 仍显示多个节点,要配合 dmesg | grep -i numa 确认内核是否真正启用了 NUMA 支持——有些平台只是暴露了 topology,但没激活内存亲和逻辑。
查 /sys/devices/system/node/ 看运行时内存状态
这个目录是内核暴露 NUMA 运行时状态的权威接口,所有文件都是实时更新的,比如进程迁移、页面回收都会立刻反映在对应节点文件里。
常用路径和用途:
-
/sys/devices/system/node/node0/meminfo—— 显示 node0 上各类内存页(Active, Inactive, File, Anon 等)的精确计数 -
/sys/devices/system/node/node0/cpulist—— 当前可调度到该节点的 CPU 列表(可能受taskset或 cgroup 约束) -
/sys/devices/system/node/node0/online—— 值为1表示该节点在线;0表示被禁用(如热拔插或内核参数numa=off)
别指望这里看到“内存起始物理地址”——它只管内存归属和使用统计,不提供地址映射。需要地址信息请转向 /proc/iomem。
结合 /proc/iomem 定位 System RAM 的真实物理地址段
/proc/iomem 是唯一能告诉你“哪段物理地址属于可用 RAM”的运行时视图。它不按 NUMA 节点组织,而是按物理地址空间线性列出所有区域。
关键操作:
- 执行
grep "System RAM" /proc/iomem,只保留顶层未缩进的行(子区域如 PCI 设备映射下的 RAM 不算) - 每行格式为
00000000-0009ffff : System RAM,其中起始-结束地址就是真实物理地址范围 - 现代 UEFI 系统常有多段不连续的
System RAM,例如80000000-9effffff和c0000000-cfffffff,它们可能分属不同 NUMA 节点
常见误区:reserved、Kernel code、ACPI Tables 区域虽然也在 RAM 地址范围内,但不可用于用户态分配;/proc/meminfo 中的 MemTotal 是这些 System RAM 段减去所有 reserved 后的总和,不是简单相加。
为什么不能只靠 free 或 top 查物理拓扑
这两个命令只报告内存用量,完全不体现物理布局:
-
free -h输出的total是/proc/meminfo中MemTotal的格式化展示,无地址、无节点归属 -
top的Mem:行同样只汇总用量,按M排序只能看进程 RSS,无法判断该 RSS 页落在哪个 NUMA 节点或物理地址段 - 它们甚至不区分 UMA 和 NUMA 架构——即使系统有 4 个 NUMA 节点,
free也只会报一个总数
真正做内存调优(比如绑核+绑内存、避免跨节点分配)时,必须交叉比对 numactl --hardware、/sys/devices/system/node/ 和 /proc/iomem 三者输出。漏掉任一环节,就容易把“逻辑可见”当成“物理可达”。


















