You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinAPI VirtualQueryEx统计进程内存与任务管理器数值不符问题

进程内存统计差异:自定义WinAPI函数与任务管理器数值不符的原因

你的代码逻辑存在两处关键问题,同时你统计的内存指标和任务管理器的统计口径完全不同,两者共同导致了数值差异。

一、代码逻辑的错误

  1. 32位地址截断问题
    你用DWORD类型存储内存地址(currAddr和mbi.BaseAddress的强制转换),在64位系统下,64位内存地址会被截断为32位,这会导致遍历内存区域时出现地址错误,要么漏统计大量内存区域,要么错误触发重复地址判断提前终止循环。正确的做法是用LPVOID或UINT_PTR/SIZE_T来存储地址,避免截断。

  2. 多余的重复地址判断
    VirtualQueryEx本身是按进程虚拟地址空间的顺序遍历内存区域的,绝不会返回重复的基地址。你添加的tempAddresses完全多余,反而会因为地址截断问题错误判定地址重复,导致循环提前终止,统计不完整。

二、统计口径的差异

任务管理器“详细信息”页显示的“内存”默认是专用工作集(Private Working Set):

  • 这部分是进程独占的、已经加载到物理内存中的内存,不包含共享内存,也不包含已经提交但尚未被访问(仍在虚拟内存分页文件中)的私有内存。

而你的代码统计的是所有提交的私有虚拟内存(MEM_COMMIT + MEM_PRIVATE):

  • 这包括了所有进程已经向系统申请并提交的私有虚拟内存,不管是否已经被加载到物理内存,范围比专用工作集大得多,数值自然更高。

修正方案

1. 修正后的提交私有内存统计代码

如果你的需求确实是统计所有提交的私有虚拟内存,修正地址处理和去掉多余判断后的代码如下:

#include <Windows.h>

SIZE_T GetProcessCommitedMemorySize(const HANDLE hProcess)
{
    MEMORY_BASIC_INFORMATION mbi;
    SIZE_T totalMemory = 0;
    LPVOID currAddr = nullptr;

    while (VirtualQueryEx(hProcess, currAddr, &mbi, sizeof(mbi)) == sizeof(mbi))
    {
        // 移动到下一个内存区域
        currAddr = reinterpret_cast<LPVOID>(
            reinterpret_cast<UINT_PTR>(mbi.BaseAddress) + mbi.RegionSize
        );

        if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE)
        {
            totalMemory += mbi.RegionSize;
        }
    }

    return totalMemory;
}

2. 匹配任务管理器数值的代码

如果要和任务管理器显示的内存数值对齐,应该使用GetProcessMemoryInfo函数获取专用工作集大小,这个接口直接返回系统统计的进程内存指标,无需手动遍历:

#include <Windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")

SIZE_T GetProcessPrivateWorkingSet(const HANDLE hProcess)
{
    PROCESS_MEMORY_COUNTERS_EX pmc;
    if (GetProcessMemoryInfo(hProcess, reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmc), sizeof(pmc)))
    {
        // PrivateUsage就是专用工作集大小,和任务管理器显示的数值一致
        return pmc.PrivateUsage;
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Noam Patai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:55:16