getphysicallyinstalledsystemmemory可获取主板实际安装内存容量(kb),但仅支持windows vista+,需动态加载、检查函数指针并用.quadpart读取ulonglong,不反映bios/驱动屏蔽情况。

Windows 下用 GetPhysicallyInstalledSystemMemory 获取物理内存容量
这个 API 能读取主板上实际安装的内存容量(单位是 KB),比 GlobalMemoryStatusEx 返回的“可用/已用”更接近硬件真实值。但它只在 Windows Vista 及以后支持,且需要链接 kernel32.lib。
- 调用前必须检查函数指针是否非空,因为旧系统可能不导出该符号
- 返回值是
ULARGE_INTEGER,需用.QuadPart成员转为uint64_t,否则 32 位程序可能截断 - 它不反映内存是否被 BIOS 或驱动屏蔽,比如某些服务器启用内存镜像后,这里仍显示总安装量
typedef BOOL (WINAPI *PFN_GetPhysicallyInstalledSystemMemory)(PULONGLONG);
HMODULE h = GetModuleHandleA("kernel32.dll");
PFN_GetPhysicallyInstalledSystemMemory pfn = (PFN_GetPhysicallyInstalledSystemMemory)
GetProcAddress(h, "GetPhysicallyInstalledSystemMemory");
ULONGLONG bytes = 0;
if (pfn && pfn(&bytes)) {
uint64_t total_kb = bytes; // 注意:单位是 KB
}
Linux 下读取 /sys/devices/system/memory/block_size_bytes 和 /sys/devices/system/memory 目录
Linux 没有统一 syscall 获取“总安装内存”,但可通过 sysfs 推算:每个 memoryX 子目录代表一个内存块,online 文件为 1 表示启用,state 为 online 同样表示启用。关键在于先读 block_size_bytes 得到每个块大小,再统计在线块数。
-
block_size_bytes是十六进制字符串,需用std::stoull(..., nullptr, 16)解析 - 遍历
/sys/devices/system/memory时跳过memory0(它只是占位符),从memory1开始 - 部分内核(如某些 ARM 配置)可能禁用 memory hotplug,导致该路径不存在,此时应回退到
/proc/meminfo的MemTotal:行
获取内存型号需依赖 SMBIOS —— Windows 用 WMI,Linux 用 dmidecode 或 libdmi
操作系统本身不维护内存条型号信息,必须查 SMBIOS 表。用户态程序无法直接读取原始 SMBIOS 数据(需要 ring-0 权限或内核模块),所以得走间接路径。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- Windows 上推荐用 WMI 查询
Win32_PhysicalMemory类,字段PartNumber和Manufacturer最接近“型号” - Linux 上若无
dmidecode(常因权限被禁),可尝试读/sys/firmware/dmi/tables/DMI(需 root 且内核开启 CONFIG_DMI_SYSFS) - 注意:多通道内存可能返回多个条目,但
SerialNumber常为空;Capacity字段单位是字节,但某些老 BIOS 会填 0
跨平台封装时别硬拼“总容量 + 型号”逻辑
很多库(如 psutil 的 C++ 绑定)把内存容量和型号混在一起返回,但二者来源、权限、稳定性完全不同:容量能稳定获取,型号则高度依赖环境和权限。强行合并容易掩盖失败原因。
- 建议拆成两个独立接口:
get_total_physical_memory_bytes()和get_memory_modules(),后者返回 vector of struct - Linux
dmidecode调用要加sudo判断,不能静默失败;Windows WMI 查询超时设为 3 秒较稳妥 - 嵌入式或容器环境(如 Docker 默认禁用
sysfsdmi)下,型号几乎必然为空,这时返回空 vector 比抛异常更合理
真正麻烦的不是读数据,而是判断“这个值到底代表什么”——MemTotal 包含预留内存,GetPhysicallyInstalledSystemMemory 不含坏块,SMBIOS 的 Speed 字段可能是 0 或无效值。每层抽象都漏了一点真相。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










