不能。GetProcessMemoryInfo仅返回当前进程内存使用情况,不提供系统物理内存峰值;需用GlobalMemoryStatusEx实时采样或性能计数器自行跟踪峰值。

GetProcessMemoryInfo 能不能直接拿到系统物理内存峰值?
不能。GetProcessMemoryInfo 只能查当前进程的内存使用情况,返回的是 PROCESS_MEMORY_COUNTERS 或 PROCESS_MEMORY_COUNTERS_EX 结构体,里面没有“系统级峰值”字段。它连本进程的历史峰值都拿不到(PeakWorkingSetSize 是进程自启动以来的最高工作集,但不是系统全局的物理内存占用峰值)。
系统物理内存峰值该去哪查?
Windows 没有公开 API 直接暴露“系统物理内存占用历史峰值”,因为这个值本身不被内核持续追踪和保留。但你可以通过以下两种方式逼近:
-
实时采样 + 自行记录最大值:调用
GlobalMemoryStatusEx获取MEMORYSTATUSEX,反复读取ullTotalPhys - ullAvailPhys(已用物理内存),自己维护一个运行时最大值; -
查性能计数器(PerfCounter):使用
PdhOpenQuery+PdhAddCounter订阅\Memory\% Committed Bytes In Use或\Memory\Available MBytes,再推算出已用值并跟踪峰值——这是更接近“系统级监控工具”的做法,但开销略大、初始化复杂。
多数场景下,第一种足够用。注意:GlobalMemoryStatusEx 返回的是瞬时快照,频率太高(如
为什么 GetProcessMemoryInfo 的 PeakWorkingSetSize 不等于任务管理器里的“峰值工作集”?
任务管理器显示的“峰值工作集”其实是从 ETW(Event Tracing for Windows)事件中提取的,底层依赖 PerfCounter 的 \Process(_Total)\Working Set Peak,而 GetProcessMemoryInfo 返回的 PeakWorkingSetSize 是 NtQueryInformationProcess 在进程生命周期内捕获的最高值,两者采集路径不同、更新时机不同、甚至精度单位也可能有微小差异(比如是否含共享页、是否四舍五入到页面边界)。
- 任务管理器的数据更平滑、带聚合,适合用户观察;
-
GetProcessMemoryInfo的结果更“原始”,但只反映本进程,且一旦进程退出,该值就丢失; - 如果你在调试内存泄漏,别只信
PeakWorkingSetSize—— 它可能被系统回收行为掩盖(比如工作集被 Trim,但私有字节PrivateUsage仍在涨)。
实战代码片段:用 GlobalMemoryStatusEx 统计系统物理内存使用峰值
#include <windows.h>
#include <iostream><p>int main() {
MEMORYSTATUSEX mem{};
mem.dwLength = sizeof(mem);
ULONGLONG peakUsedBytes = 0;</p>
<pre class="brush:php;toolbar:false;">while (true) {
if (GlobalMemoryStatusEx(&mem)) {
ULONGLONG used = mem.ullTotalPhys - mem.ullAvailPhys;
if (used > peakUsedBytes) peakUsedBytes = used;
std::wcout <p>}
</p>
这段代码没做异常终止、线程安全或长时间运行的持久化,仅作逻辑示意。真实项目里要加退出条件、避免整数溢出(ullTotalPhys 可能为 0)、考虑 NUMA 节点差异(GlobalMemoryStatusEx 返回的是全局汇总值,不区分节点)。
真正难的不是调哪个函数,而是想清楚你要的“峰值”到底指什么:是开机以来的最大值?最近一小时?还是某次压力测试中的瞬时极值?定义模糊,API 就无从匹配。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











