Harry Asked:2020-12-19 01:00:13 +0000 UTC2020-12-19 01:00:13 +0000 UTC 2020-12-19 01:00:13 +0000 UTC 如何测量使用的内存量 772 受到这个答案的启发。突然间我意识到我知道如何衡量一个程序的性能,但是如何确定它需要多少内存——这是我在教育方面的差距:) 拦截new和delete?令人怀疑的是,不难相信一切都只能通过这些运营商运作。 总之,没有人会告诉你如何以最好、最可靠、最准确的方式来做,最好不是从外部,而是从程序本身? 更具体地说 - Windows,使用 Visual C++ 2017。 c++ 1 个回答 Voted Best Answer MSDN.WhiteKnight 2020-06-30T14:52:10Z2020-06-30T14:52:10Z 有几个 API 用于获取有关进程内存的信息,其中最有趣的是: GetProcessMemoryInfo函数 性能计数器 HeapSummary函数 代码示例: #include <windows.h> #include <stdio.h> #include <psapi.h> #include "pdh.h" #pragma comment( lib, "Pdh.lib" ) long GetPrivateWorkingSet(const wchar_t* process) { PDH_HQUERY query; PDH_HCOUNTER counter; PDH_FMT_COUNTERVALUE counterVal; const wchar_t* name = L"\\Process(%s)\\Working Set - Private"; wchar_t buf[1024]=L""; swprintf_s(buf, 1024, name, process); PdhOpenQuery(NULL, NULL, &query); PDH_STATUS res = PdhAddEnglishCounter(query, buf, NULL, &counter); res = PdhCollectQueryData(query); PdhGetFormattedCounterValue(counter, PDH_FMT_LONG, NULL, &counterVal); long ret = counterVal.longValue; PdhCloseQuery(query); return ret; } void PrintMemory() { PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); printf("Private committed memory: %u B\nWorking set: %u B\n", (UINT)pmc.PrivateUsage, (UINT)pmc.WorkingSetSize); printf("Private working set: %u B\n", (UINT)GetPrivateWorkingSet(L"Program")); HANDLE heaps[20]; HEAP_SUMMARY hs; DWORD cHeaps = GetProcessHeaps(20, heaps); for (DWORD i = 0; i < cHeaps; i++) { memset(&hs, 0, sizeof(hs)); hs.cb = sizeof(hs); if (HeapSummary(heaps[i], 0, &hs) == FALSE) printf("HeapSummary failed"); printf("Heap #%u size: %u B\n", (UINT)i, (UINT)hs.cbAllocated); } printf("\n"); } int main() { //первый запуск нужен для прогрева, т.е чтобы инициализировать внутренние структуры API //(так как API счетчиков производительности сам выделяет память при первом запуске) PrintMemory(); //второй запуск, соответственно, дает достоверные значения PrintMemory(); getchar(); } 我在这里使用的指标是: 私有提交内存- 处于 MEM_COMMIT 状态的进程的虚拟内存量由该进程独占。MEM_COMMIT 状态意味着在页面文件中已经为这块内存分配了空间,在物理内存中可以分配也可以不分配。该值不包括在不同进程之间共享的内存——内存映射文件和加载的 DLL,因此是“私有的”。听起来很复杂,但实际上这是进程“吃掉”内存的主要指标。 工作集- 分配给进程的物理内存总量,包括在多个进程之间共享。 私有工作集- 此进程独占的物理内存量。这个指标比上一个指标更有用,但获取难度更大。 堆大小——分配的动态内存量(除了我们通过 直接分配的new,还包括库内部分配的)。 使用这些指标中的哪一个在很大程度上取决于具体情况。如果我们谈论体育编程和限制用于解决问题的内存量,私有提交的内存很有趣。在评估系统负载时,物理内存更为重要,因为它比交换文件中的空间更稀缺。
有几个 API 用于获取有关进程内存的信息,其中最有趣的是:
代码示例:
我在这里使用的指标是:
私有提交内存- 处于 MEM_COMMIT 状态的进程的虚拟内存量由该进程独占。MEM_COMMIT 状态意味着在页面文件中已经为这块内存分配了空间,在物理内存中可以分配也可以不分配。该值不包括在不同进程之间共享的内存——内存映射文件和加载的 DLL,因此是“私有的”。听起来很复杂,但实际上这是进程“吃掉”内存的主要指标。
工作集- 分配给进程的物理内存总量,包括在多个进程之间共享。
私有工作集- 此进程独占的物理内存量。这个指标比上一个指标更有用,但获取难度更大。
堆大小——分配的动态内存量(除了我们通过 直接分配的
new
,还包括库内部分配的)。使用这些指标中的哪一个在很大程度上取决于具体情况。如果我们谈论体育编程和限制用于解决问题的内存量,私有提交的内存很有趣。在评估系统负载时,物理内存更为重要,因为它比交换文件中的空间更稀缺。