GetPhysicallyInstalledSystemMemory 是 Windows Vista+ 唯一能直接读取插槽级物理内存容量的 API,返回 SPD 芯片标称值(KB),需 64 位程序调用并链接 kernel32.lib,虚拟机需支持 SPD 模拟。

Windows 下用 GetPhysicallyInstalledSystemMemory 获取插槽级物理内存容量
这个 API 是 Windows Vista+ 提供的唯一能直接读取“实际插槽中安装的内存条容量”的方式,它绕过 BIOS/UEFI 报告偏差,返回的是 SPD(串行存在检测)芯片里写死的标称值,单位是 KB。
常见错误是误用 GlobalMemoryStatusEx —— 它只返回当前 OS 可见的总物理内存(ullTotalPhys),不区分插槽,且受启动参数(如 /PAE、/MAXMEM)、Secure Boot 内存保留、硬件保留区影响,数值常比插槽总和小。
-
GetPhysicallyInstalledSystemMemory返回值是DWORD64,需注意 32 位程序在 >4GB 插槽总容量时可能截断(建议用 64 位构建) - 必须链接
kernel32.lib,且运行在真实物理机或支持内存 SPD 模拟的 Hyper-V Gen 2 虚拟机上;VMware/VirtualBox 默认不暴露 SPD,会返回 0 - 示例调用:
DWORD64 totalKb = 0; if (GetPhysicallyInstalledSystemMemory(&totalKb)) { std::cout << "插槽总容量: " << totalKb / 1024 / 1024 << " GB\n"; }
Linux 下解析 /sys/firmware/dmi/entries/17-*/raw 提取内存设备信息
Linux 没有统一 syscall 获取插槽分布,依赖 DMI/SMBIOS 数据。内核通过 dmidecode 工具可读,但 C++ 程序需自行解析原始二进制数据 —— 关键是定位类型 17(Memory Device)结构体。
容易踩的坑:不是所有系统都启用 CONFIG_DMI 或挂载 firmware fs;某些 ARM 服务器或容器环境(如 docker run --privileged 缺失)根本无此路径。
立即学习“C++免费学习笔记(深入)”;
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 每个类型 17 条目含插槽名(
Location Tag)、厂商(Manufacturer)、大小(Size字段,单位 MB,0x8000 表示 32GB+,需查扩展字段) -
/sys/firmware/dmi/entries/下可能有多个 17-* 子目录,需遍历;若不存在,退回到执行dmidecode -t memory并 parse stdout(需 root 或cap_sys_rawio) - 总物理内存应以
sysinfo(2)的mem_unit * sysinfo.totalram为准,它反映内核实际管理的页帧数,比 DMI 更可靠
跨平台总物理内存:别信 sysconf(_SC_PHYS_PAGES) 在 macOS 上的返回值
macOS 的 sysconf(_SC_PHYS_PAGES) 实际返回的是“可用物理页数”,而非总量 —— 它已扣除内核预留、I/O 映射等不可用区域,导致结果比真实 RAM 小 5–15%。正确做法是调用 host_statistics64 + HOST_VM_INFO64。
对比其他平台:
- Linux:
sysinfo(2)的totalram最准,它直接读/proc/meminfo的MemTotal - Windows:
GetNativeSystemInfo不适用,它只给地址空间限制;必须用GlobalMemoryStatusEx的ullTotalPhys - 所有平台都要注意:启用
hugepages、kdump或 Secure Boot 的 TDX/SEV 内存加密后,OS 可见总量必然小于标称物理容量
为什么不能仅靠 dmidecode 或 WMI 就完事?
因为 DMI 数据由固件提供,而厂商常填错 SPD 信息:同一插槽反复报告 0、多条内存被合并成一条、NVDIMM 和 DDR5 混插时类型字段乱码。WMI 的 Win32_PhysicalMemory 类同样继承这些缺陷,且在 Server Core 或 Nano Server 中默认禁用 WMI 服务。
真正健壮的做法是分层验证:
- 先读 DMI/WMI 获取插槽拓扑与标称容量
- 再用 OS 接口(
sysinfo/GlobalMemoryStatusEx/host_statistics64)获取实际可用总量 - 若两者差值 >5%,触发警告并降级为仅显示 OS 层数据 —— 用户需要知道“BIOS 说的和系统看到的不一致”
插槽级细节在生产环境排障中价值有限,但总量偏差超过 1GB 就得怀疑是否开启了内存压缩、kdump 预留或 UEFI 固件 Bug。

















