当前的内存使用情况显示始终比任务管理器大14MB [英] Current memory usage display is always ~14MB more than task manager

查看:378
本文介绍了当前的内存使用情况显示始终比任务管理器大14MB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用

I'm currently using the code in this answer, with some slight modifications as suggested in the comments. However, no matter how many objects I allocate in memory, the listed memory usage is always ~14MB more than what task manager lists. Why could this be?

std::stringstream ss;

PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
SIZE_T physMemUsedByMe = pmc.WorkingSetSize;

ss << "\nMEM: " << (physMemUsedByMe / 1024 / 1024) << " MB";    

debugText.setString(ss.str());

正常构建的结果:

debugText:

任务管理器:

资源监控器:

分配10,000个虚拟对象时的结果:

debugText:

任务管理器:

资源监控器:

使用Resource Monitor(perfmon)作为注释建议后,我发现Working Set的列与我正在使用的内存列表功能匹配.但是,我仍然困惑为什么Working Set列和Private列之间有〜14MB的差异(后者是Task Manager似乎使用的).为什么会这样?

After using Resource Monitor (perfmon) as the comments suggested, I found that the column for Working Set matches the memory-listing function I'm using. However, I'm still perplexed as to why there's a ~14MB difference between the Working Set column and the Private column (the latter of which is what Task Manager appears to use). Why is this the case?

推荐答案

任务管理器不使用Win32 API GetProcessMemoryInfo()函数.它使用NT API ZwQueryInformationProcess()函数,将ProcessInformationClass参数设置为ProcessVmCounters.

Task Manager does not use the Win32 API GetProcessMemoryInfo() function. It uses the NT API ZwQueryInformationProcess() function, setting the ProcessInformationClass parameter to ProcessVmCounters.

从Windows 10开始,定义了以下结构(在ntddk.h中):

Beginning in Windows 10, the following structure is defined (in ntddk.h):

typedef struct _VM_COUNTERS_EX2 {
    VM_COUNTERS_EX CountersEx;
    SIZE_T PrivateWorkingSetSize;
    ULONGLONG SharedCommitUsage;
} VM_COUNTERS_EX2, *PVM_COUNTERS_EX2;

任务管理器使用VM_COUNTERS_EX2类似于以下代码:

Task Manager uses VM_COUNTERS_EX2 similar to the following code:

VM_COUNTERS_EX2 vm;
ZwQueryInformationProcess(hProcess, ProcessVmCounters, &vm, sizeof(vm), 0);

在内存(专用工作集)"列中显示的值是vm.PrivateWorkingSetSize字段.

The value it shows for the "Memory(private working set)" column is the vm.PrivateWorkingSetSize field.

目前看来还没有Win32 API类似物.您如何看待这一点:

It looks like a Win32 API analog for this does not exist at this time. How you can see this:

typedef struct _VM_COUNTERS_EX {
    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;// note this !!
    ULONG PageFaultCount;
    SIZE_T PeakWorkingSetSize;
    SIZE_T WorkingSetSize;
    SIZE_T QuotaPeakPagedPoolUsage;
    SIZE_T QuotaPagedPoolUsage;
    SIZE_T QuotaPeakNonPagedPoolUsage;
    SIZE_T QuotaNonPagedPoolUsage;
    SIZE_T PagefileUsage;
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivateUsage;
} VM_COUNTERS_EX;

VM_COUNTERS_EX2VM_COUNTERS_EX基极靠近PROCESS_MEMORY_COUNTERS_EX,但不完全相同(没有[Peak]VirtualSize)成员). GetProcessMemoryInfo()内部调用ZwQueryInformationProcess(hProcess, ProcessVmCounters),然后将VM_COUNTERS_EX复制到PROCESS_MEMORY_COUNTERS_EX.

The VM_COUNTERS_EX base of VM_COUNTERS_EX2 is very near PROCESS_MEMORY_COUNTERS_EX but not exact (there are no [Peak]VirtualSize) members). GetProcessMemoryInfo() internally calls ZwQueryInformationProcess(hProcess, ProcessVmCounters) and then copies the VM_COUNTERS_EX to PROCESS_MEMORY_COUNTERS_EX.

在Windows 10的任务管理器中,内存(单个进程保留的物理内存)"列显示PrivateWorkingSet(以1024字节为增量).此相同的值显示在详细信息"选项卡(专用工作集)下.出于未知原因,该值以1000字节为增量显示,因此实际值始终高出1.024倍.

In Task Manager on Windows 10, the "Memory(physical memory reserved by individual processes)" column shows PrivateWorkingSet (in increments of 1024 bytes). This same value is shown under the "Details" tab (private working set). For an unknown reason, that value is shown in increments of 1000 bytes, so the real value is always 1.024 times higher.

但是您使用总计"工作集-WorkingSetSize-这是私有"和共享"工作集的总和(您需要在详细信息"选项卡中添加列才能查看此内容,默认情况下仅显示私有内存).因此,结果之间存在恒定的差异(14 MB)-这是共享的"工作集(通常是常见的DLL,例如ntdll.dllkerner32.dllkernelbase.dll等).分配内存(10,000个虚拟对象)时,这种差异不会改变. 专用"工作集在增长,但是共享"工作集保持不变(因为没有新的DLL被加载/卸载).

But you use the "total" working set - WorkingSetSize - which is the sum of the "private" and "shared" working sets (you need the add columns to the Details tab to view this, by default only the private memory is shown). So, there is a constant difference in the result (14 MB) - this is the "shared" working set (usually common DLLs, like ntdll.dll, kerner32.dll, kernelbase.dll, etc). This difference does not change when you allocate memory (10,000 dummy objects). The "private" working set grows, but the "shared" working set remains unchanged (because no new DLLs are loaded/unloaded).

如果要像任务管理器一样显示内存,请使用NT API中VM_COUNTERS_EX2PrivateWorkingSetSize成员.如果您不能使用它,那么您将获得与任务管理器不同的结果.

If you want to show memory like Task Manager does, use the PrivateWorkingSetSize member of VM_COUNTERS_EX2 from the NT API. If you cannot use that, then you will have different results than Task Manager.

如果您不喜欢NT API或不理解它,这不是我的问题(或者也许有人可以 now 通过使用一些已记录的" API来获得PrivateWorkingSetSize?) .如果任务管理器使用NT API,这也不是我的选择.

If you do not like the NT API, or do not understand it, this is not my problem (or maybe somebody can now get the PrivateWorkingSetSize by using some "documented" API?). If Task Manager uses the NT API, this is also not my choice.

这篇关于当前的内存使用情况显示始终比任务管理器大14MB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆