不能。GetProcessMemoryInfo 的 PeakWorkingSetSize 仅反映本进程工作集历史峰值,非系统级物理内存峰值;Windows 不提供直接获取系统物理内存历史峰值的 API,需自行周期性采样 GlobalMemoryStatusEx 并维护最大值。

Windows 下用 GetProcessMemoryInfo 拿不到物理内存峰值?
不能。这个函数返回的是当前进程的内存快照,PeakWorkingSetSize 是进程工作集峰值,不是系统级物理内存占用峰值。系统全局的物理内存使用峰值(即自开机以来 RAM 使用量的最高点)没有直接暴露给用户态 API —— Windows 本身不持续记录这个值。
真正能反映“系统物理内存占用峰值”的,是性能计数器中的 \Memory\Committed Bytes Peak 或 \Memory\Pool Paged Bytes Peak 等指标,但它们语义不同:前者是已提交虚拟内存的峰值,后者是分页池峰值,都不等于物理 RAM 占用峰值。
实操建议:
- 若目标是监控本进程内存压力,用
GetProcessMemoryInfo+PeakWorkingSetSize即可,它接近该进程曾占有的最大物理内存(受工作集策略影响) - 若真要估算系统级物理内存峰值,只能周期性采样
GlobalMemoryStatusEx中的ullTotalPhys - ullAvailPhys,自己维护最大值 - 注意:Windows 不提供原子化的“系统物理内存历史峰值”变量,任何所谓“获取峰值”的操作,本质都是你自己的采样+记录
Linux 下读 /proc/meminfo 能拿到峰值吗?
不能。/proc/meminfo 只提供瞬时快照:MemTotal、MemAvailable、MemFree 都是当前值;MemAvailable 是内核估算的可用内存,不是历史峰值。
Linux 内核不默认记录物理内存使用峰值。但你可以通过以下方式间接逼近:
- 用
sysinfo()系统调用读取struct sysinfo,其中totalram和freeram是当前值,仍需自行采样计算差值并跟踪最大值 - 启用
perf或eBPF工具(如bpftrace)监听内存分配事件,但开销大、非标准、不可移植 - 依赖外部监控服务(如
collectd、node_exporter)长期采集并存储历史数据,再查其峰值
没有一行代码能“直接读出系统物理内存历史峰值”,所有方案都绕不开“你自己定时读 + 自己存最大值”这个环节。
C++ 跨平台采样并维护系统物理内存峰值的最小可行实现
核心逻辑就是:定时读当前已用物理内存 = 总物理内存 − 当前空闲内存,然后更新本地最大值。关键在如何跨平台读这两个值。
Windows 示例(使用 GlobalMemoryStatusEx):
MEMORYSTATUSEX mem; mem.dwLength = sizeof(mem); GlobalMemoryStatusEx(&mem); uint64_t used = mem.ullTotalPhys - mem.ullAvailPhys; peak_used = std::max(peak_used, used);
Linux 示例(解析 /proc/meminfo):
std::ifstream f("/proc/meminfo");
std::string line;
uint64_t total = 0, free = 0;
while (std::getline(f, line)) {
if (line.rfind("MemTotal:", 0) == 0) total = std::stoull(line.substr(9)) * 1024;
else if (line.rfind("MemAvailable:", 0) == 0) free = std::stoull(line.substr(13)) * 1024;
}
uint64_t used = total - free;
peak_used = std::max(peak_used, used);
注意事项:
-
MemAvailable比MemFree更合理,它包含可回收的 page cache,更接近真实可用量 - 采样间隔不宜过密(如低于 1s),避免 I/O 或系统调用开销反成瓶颈
- 多线程更新
peak_used时必须加锁或用std::atomic<uint64_t></uint64_t> - 该峰值仅对当前运行周期有效,程序重启后归零 —— 如需持久化,得自己写到文件或数据库
为什么监控工具显示的“内存峰值”看起来很准?
因为它们不是调用某个神奇 API 一次性读出来的,而是长期运行、高频采样、持续更新内部最大值的结果。比如 htop 的峰值栏,本质是它启动后每 100ms 读一次 /proc/meminfo,自己维护了一个 max_used 变量。
真正容易被忽略的点:
- “物理内存占用峰值”本身是个有歧义的概念:是指某块 RAM 曾被映射过的最高时刻?还是指工作集大小的历史最大?不同场景下定义不同
- 内核可能因内存压缩(zswap)、内存合并(KSM)、透明大页(THP)等机制,让“物理占用”和“逻辑用量”严重脱钩
- 容器环境(Docker / cgroups v2)下,进程看到的其实是 cgroup memory limit 内的统计,和宿主机物理内存峰值完全不是一回事
别指望一个函数调用就给你答案。峰值是时间维度上的结果,不是状态快照。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











