windows下用getprocessmemoryinfo获取进程内存最可靠,需目标进程handle并设process_query_information和process_vm_read权限,workingsetsize反映工作集大小,privateusage表示私有物理内存,cb字段必须预设为结构体大小。

Windows下用 GetProcessMemoryInfo 获取进程内存使用量
直接调用 Windows API 是最可靠的方式,前提是已有目标进程的 HANDLE(且具有 PROCESS_QUERY_INFORMATION 和 PROCESS_VM_READ 权限)。GetProcessMemoryInfo 返回的是 PROCESS_MEMORY_COUNTERS 结构,其中 WorkingSetSize(工作集)和 PrivateUsage(私有字节)最常用。
常见错误是忽略权限检查或 HANDLE 有效性验证:打开进程失败时返回 INVALID_HANDLE_VALUE,但很多人直接传给 GetProcessMemoryInfo 导致返回 false 且不报错原因。
- 必须用
OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)获取句柄 -
PROCESS_MEMORY_COUNTERS的cb字段必须在调用前设为sizeof(PROCESS_MEMORY_COUNTERS),否则 API 忽略请求 -
PrivateUsage更接近“该进程独占的物理内存”,而WorkingSetSize包含共享页,数值通常更大 - 若目标进程已退出,
GetProcessMemoryInfo返回 false,GetLastError()为ERROR_INVALID_HANDLE
Linux下读取 /proc/[pid]/statm 和 /proc/[pid]/status
Linux 没有统一 API,靠解析 /proc 文件系统。对大多数场景,/proc/[pid]/statm 更轻量;需要更详细分类(如 RSS、VMS、共享内存等)则看 /proc/[pid]/status。
容易踩的坑是没处理进程已消亡或权限不足的情况:读 /proc/[pid]/statm 失败时返回空或 errno 为 ESRCH(无此进程)或 EACCES(权限不够),而非抛异常。
-
/proc/[pid]/statm一行六列,单位是页(page),需乘以getpagesize()转为字节;第二列为 RSS(常驻集大小) -
/proc/[pid]/status中找VmRSS:行,值单位是 kB,比statm更直观,但文件 I/O 开销略大 - 注意
pid可能被复用——拿到 pid 后立即读/proc/[pid]/statm,避免竞态 - 普通用户无法读其他用户的
/proc/[pid]/目录,除非有ptrace权限或目标进程属同一用户
C++跨平台封装要注意的兼容点
没有标准库函数能跨平台查进程内存,强行封装时,核心分歧在“什么算内存占用”。Windows 的 PrivateUsage ≈ Linux 的 Private_Dirty + Private_Clean(来自 /proc/[pid]/smaps),但后者默认不可读,普通场景只能退回到 VmRSS 或 statm 的近似值。
- 不要试图统一返回“准确物理内存”——不同系统定义不同,
RSS和WorkingSetSize都是合理近似,但语义不等价 - Linux 下若需
Private_*字段,必须读/proc/[pid]/smaps,但该文件可能超大(GB 级),建议用std::ifstream配合std::string_view扫描关键行,而非全读 - Windows 上启用
SeDebugPrivilege才能打开系统进程(如svchost.exe),普通程序几乎拿不到;Linux 下 root 才能读其他用户进程,二者权限模型本质不同,别硬套同一套错误处理逻辑
实际使用中容易被忽略的细节
获取到的数值只是瞬时快照,且受 OS 调度影响极大。比如刚启动的进程 RSS 可能很小,但触发一次 malloc 后立刻跳升;后台进程可能被 OS 换出部分页,导致 RSS 缩水——这不是泄漏,是正常行为。
- 单次采样意义有限,监控类用途应至少间隔 500ms 以上连续采样,并观察趋势而非绝对值
- Windows 的
WorkingSetSize包含共享 DLL 的内存,多个进程共用同一份系统 DLL 时,加总后会远超物理内存总量 - Linux 的
VmRSS不包含 swap 中的页,而VmSize(虚拟内存大小)又包含未分配的 mmap 区域,两者都非“真实占用” - 如果目标进程是 32 位而你的程序是 64 位,在 Windows 上用
OpenProcess没问题,但某些旧版 WMI 查询可能失败,别混用接口
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











