标签:taskmanager c memory windows winapi
我目前正在使用this answer中的代码,并在评论中建议稍作修改.但是,无论我在内存中分配了多少个对象,列出的内存使用量总是比任务管理器列出的大约多14MB.为什么会这样?
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:
任务管理器:
资源监控:
编辑:
使用资源监视器(perfmon)作为建议的注释后,我发现Working Set的列与我正在使用的内存列表函数相匹配.但是,我仍然感到困惑的是,为什么工作集列和私有列之间存在~14MB的差异(后者是任务管理器似乎使用的).为什么会这样?
解决方法:
任务管理器不使用Win32 API GetProcessMemoryInfo()函数.它使用NT API ZwQueryInformationProcess()函数,将ProcessInformationClass参数设置为ProcessVmCounters.
从Windows 10开始,定义了以下结构(在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:
VM_COUNTERS_EX2 vm;
ZwQueryInformationProcess(hProcess, ProcessVmCounters, &vm, sizeof(vm), 0);
它显示的“内存(私有工作集)”列的值是vm.PrivateWorkingSetSize字段.
它看起来像Win32 API模拟此时不存在.你怎么看这个:
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_EX2的VM_COUNTERS_EX基础非常接近PROCESS_MEMORY_COUNTERS_EX但不精确(没有[Peak] VirtualSize)成员). GetProcessMemoryInfo()在内部调用ZwQueryInformationProcess(hProcess,ProcessVmCounters),然后将VM_COUNTERS_EX复制到PROCESS_MEMORY_COUNTERS_EX.
在Windows 10上的任务管理器中,“内存(各个进程保留的物理内存)”列显示PrivateWorkingSet(以1024字节为增量). “详细信息”选项卡(私有工作集)下显示相同的值.由于未知原因,该值以1000字节为增量显示,因此实际值总是高1.024倍.
但是你使用“总”工作集 – WorkingSetSize – 它是“私有”和“共享”工作集的总和(你需要在Details选项卡中添加列来查看它,默认情况下只显示私有内存) .因此,结果中存在恒定的差异(14 MB) – 这是“共享”工作集(通常是常见的DLL,如ntdll.dll,kerner32.dll,kernelbase.dll等).分配内存(10,000个虚拟对象)时,这种差异不会改变. “私有”工作集增长,但“共享”工作集保持不变(因为没有加载/卸载新的DLL).
如果要像任务管理器那样显示内存,请使用NT API中的VM_COUNTERS_EX2的PrivateWorkingSetSize成员.如果您不能使用它,那么您将获得与任务管理器不同的结果.
如果您不喜欢NT API,或者不理解它,这不是我的问题(或者现在有人可以通过使用一些“记录的”API来获取PrivateWorkingSetSize?).如果任务管理器使用NT API,这也不是我的选择.
标签:taskmanager,c,memory,windows,winapi 来源: https://codeday.me/bug/20191003/1849055.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。