В настоящее время я использую код в этот ответ, с некоторыми небольшими изменениями, как предлагается в комментариях. Однако независимо от того, сколько объектов я выделяю в памяти, указанное использование памяти всегда на ~ 14 МБ больше, чем перечисляет диспетчер задач. Почему это может быть?
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
соответствует функции листинга памяти, которую я использую. Тем не менее, я все еще озадачен тем, почему есть разница ~ 14 МБ между Working Set
столбец и Private
столбец (последний из которых, по-видимому, используется диспетчером задач). Почему это так?
Диспетчер задач не использует 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_EX
основа VM_COUNTERS_EX2
очень близко 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
— которая является суммой «частного» и «общего» рабочих наборов (вам нужно добавить столбцы добавления на вкладку Подробности, чтобы просмотреть это, по умолчанию отображается только личная память). Таким образом, существует постоянная разница в результате (14 МБ) — это «общий» рабочий набор (обычно это общие библиотеки DLL, например, ntdll.dll
, kerner32.dll
, kernelbase.dll
, так далее). Эта разница не меняется при выделении памяти (10 000 фиктивных объектов). «Частный» рабочий набор увеличивается, но «общий» рабочий набор остается неизменным (поскольку новые DLL не загружаются / выгружаются).
Если вы хотите показать память, как это делает диспетчер задач, используйте PrivateWorkingSetSize
член VM_COUNTERS_EX2
из NT API. Если вы не можете использовать это, то у вас будут другие результаты, чем в диспетчере задач.
Если вам не нравится NT API или вы не понимаете его, это не моя проблема (или, может быть, кто-то может сейчас получить PrivateWorkingSetSize
используя какой-то «документированный» API?). Если диспетчер задач использует NT API, это тоже не мой выбор.
Других решений пока нет …