不能。GetProcessMemoryInfo仅返回当前进程内存使用情况,无法获取系统物理内存峰值;该峰值需通过持续采样Performance Counter(如\Memory\Available MBytes)或GlobalMemoryStatusEx计算已用内存并自行维护最大值。

GetProcessMemoryInfo 能不能拿到系统物理内存峰值
不能。这个函数只返回当前进程的内存使用情况,GetProcessMemoryInfo 的第一个参数是 HANDLE,你传进去的是自己的进程句柄(比如 GetCurrentProcess()),它压根不关心整个系统的内存历史峰值。
系统级的物理内存占用峰值(即自启动以来 RAM 使用量的最高点)Windows 并不直接暴露给用户态程序——没有现成 API 一键获取。你看到的“已使用 12.3 GB(峰值 16.1 GB)”这类信息,是任务管理器自己算出来的,靠的是持续采样 + 内存计数器缓存。
真正能反映系统物理内存峰值的 Windows 性能计数器
Windows 把这个数据藏在性能计数器(Performance Counter)里,路径是:\Memory\Commit Limit 和 \Memory\Committed Bytes 只反映提交内存,不是物理内存;真正对应“物理内存实际使用峰值”的是:\Memory\Available MBytes 的历史最低值,或者更准确地说,用 \Memory\Pool Paged Bytes + \Memory\Pool Nonpaged Bytes + \Memory\Pages/sec 等组合推算并不直接——但最实用、被任务管理器采用的指标其实是:\Memory\Physical Memory - Total 减去 \Memory\Physical Memory - Available 的实时值,再长期跟踪它的最大值。
要拿到这个峰值,你得:
- 用
PdhOpenQuery创建查询 - 用
PdhAddCounter添加\Memory\Available MBytes计数器(注意:这是“可用”内存,单位 MB) - 定期调用
PdhCollectQueryData+PdhGetFormattedCounterValue获取当前可用内存值 - 用总物理内存(可通过
GetPhysicallyInstalledSystemMemory或GlobalMemoryStatusEx获取)减去它,得到已用物理内存 - 自己维护一个运行最大值变量,持续更新
也就是说:系统本身不存“峰值”这个快照,你得自己采样、计算、记录。
为什么不用 GetPerformanceInfo?
GetPerformanceInfo(来自 psapi.h)看起来很诱人,它返回的 PERFORMACE_INFORMATION 结构里有 CommitTotal、CommitLimit、PhysicalTotal,但它**没有历史峰值字段**,所有字段都是瞬时值。即使你反复调用,也得自己比大小——它和手动查 GlobalMemoryStatusEx 没本质区别,只是多给了几个提交内存相关字段。
常见误用场景:
- 以为
pi.PhysicalTotal - pi.PhysicalAvailable就是“当前已用”,没错;但把它当“峰值”就错了 - 在服务或后台线程里每秒调一次
GetPerformanceInfo却不保存历史最大值,等于白跑 - 忽略采样频率:太低(如每分钟一次)会漏掉短时峰值;太高(如每毫秒)则
Pdh或系统调用开销反成瓶颈
一个轻量可行的实战方案(C++)
如果你只需要近似峰值(误差在几百 MB 内,且不要求毫秒级精度),推荐组合使用:
-
GlobalMemoryStatusEx获取当前ullAvailPhys和ullTotalPhys - 自己维护一个
static uint64_t s_peakUsedPhys = 0; - 每次采样后计算
used = total - avail,然后s_peakUsedPhys = max(s_peakUsedPhys, used) - 采样间隔设为 2–5 秒(避免抖动,也防 CPU 空转)
示例关键片段:
MEMORYSTATUSEX mem; mem.dwLength = sizeof(mem); GlobalMemoryStatusEx(&mem); uint64_t used = mem.ullTotalPhys - mem.ullAvailPhys; s_peakUsedPhys = std::max(s_peakUsedPhys, used);
注意:ullTotalPhys 是总物理内存,ullAvailPhys 是当前可用物理内存(不含 standby list 中可快速回收的部分),所以这个差值就是内核认为“正在被使用的物理页”数量——和任务管理器“性能”页签中显示的“已使用的内存”基本一致。
真正的难点不在代码,而在于理解 Windows 内存管理模型:standby、modified、free 页面的动态流转会让“已用”数值小幅震荡;而峰值必须跨足够长时间窗口捕获——没人能在开机后立刻知道峰值是多少,它只能随时间推移慢慢收敛。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











