必须调用GetPerformanceInfo API获取CommitPeak字段,该值为系统启动后内存提交峰值页数,需手动定义PERFORMANCE_INFORMATION结构体并正确设置Size字段,再乘以PageSize转为字节或MB。

要精确获取 Windows 系统自本次启动以来物理内存占用的峰值(即 Commit Peak),必须绕过任务管理器的采样延迟和资源监视器的聚合统计,直接调用 Windows 内核暴露的 GetPerformanceInfo 系统 API——该函数返回的 CommitTotal 和 CommitLimit 是瞬时值,而 CommitPeak 才是自系统启动后达到过的最高已提交内存总量,单位为页(PAGE_SIZE,默认 4096 字节)。
加载 psapi.dll 并声明 PerformanceInformation 结构体
先在源文件顶部包含必要头文件,并手动定义 Windows 未公开导出的 PERFORMANCE_INFORMATION 结构体。微软未在 psapi.h 中提供完整定义,若仅包含标准头文件并直接使用会导致编译失败。
添加如下代码:
#include <windows.h><br>#include <psapi.h><br>#pragma comment(lib, "psapi.lib")
立即学习“C++免费学习笔记(深入)”;
接着定义结构体(字段顺序与 Windows 内部一致,不可调整):
typedef struct _PERFORMANCE_INFORMATION {<br> DWORD Size;<br> SIZE_T CommitTotal;<br> SIZE_T CommitLimit;<br> SIZE_T CommitPeak;<br> SIZE_T PhysicalTotal;<br> SIZE_T PhysicalAvailable;<br> SIZE_T SystemCache;<br> SIZE_T KernelTotal;<br> SIZE_T KernelPaged;<br> SIZE_T KernelNonpaged;<br> SIZE_T PageSize;<br> DWORD HandleCount;<br> DWORD ProcessCount;<br> DWORD ThreadCount;<br>} PERFORMANCE_INFORMATION;
调用 GetPerformanceInfo 获取 CommitPeak
第一步:初始化结构体 Size 字段,否则 API 调用必然失败——【Size 必须精确等于结构体字节数,少一字节或多数值都会返回 ERROR_INVALID_PARAMETER】。
第二步:调用 GetPerformanceInfo。该函数位于 psapi.dll,无需额外 LoadLibrary,但首次调用可能触发 DLL 延迟加载。
第三步:检查返回值。成功时返回非零值,且 GetLastError() 为 0;失败时返回 0,需用 GetLastError() 判断原因(常见为权限不足或结构体 Size 错误)。
示例代码片段:
PERFORMANCE_INFORMATION pi = {0};<br>pi.Size = sizeof(PERFORMANCE_INFORMATION);<br>if (GetPerformanceInfo(&pi, pi.Size) == 0) {<br> DWORD err = GetLastError(); // 可打印 err 进行调试<br> return -1;<br>}
此时 pi.CommitPeak 即为自系统启动以来已提交内存的峰值页数。
将 CommitPeak 页数转换为可读的字节数与 MB 值
方法一:直接乘以系统页大小
SIZE_T peakBytes = pi.CommitPeak * pi.PageSize;
方法二:转换为 MB(除以 1024×1024),注意使用浮点运算避免整数截断:
double peakMB = static_cast<double>(peakBytes) / (1024.0 * 1024.0);</double>
⚠️ 注意:不要用 pi.CommitPeak / 256 这类硬编码近似——不同系统页大小可能为 4KB、2MB 或 1GB(如启用大页),必须严格使用 pi.PageSize。
验证 CommitPeak 是否实时更新
运行一个内存分配循环(例如 malloc + memset 持续申请 100MB 内存并保持不释放),在分配前、中、后三次调用 GetPerformanceInfo,观察 CommitPeak 数值是否单调递增且最终稳定在最大分配量附近。
这一步能确认你获取的确实是“历史峰值”,而非当前瞬时值——【CommitPeak 不会回落,只增不减,直到下次系统重启】。


















