Я пытаюсь узнать как детали работы с памятью, а также как измерить ее с помощью C ++. Я знаю, что под Windows, быстрый способ получить объем оперативной памяти, используемой текущим процессом приложения, при включении <Windows.h>
, является:
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
(uint64_t)info.WorkingSetSize;
Затем я использовал это для запуска очень простого теста:
#include <iostream>
#include <Windows.h>"
int main(void)
{
uint64_t currentUsedRAM(0);
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
currentUsedRAM = info.WorkingSetSize;
const int N(1000000);
int x[N]; //in the second run, comment this line out
int y[N]; //in the second run, comment this line out
//int *x = new int[N]; //in the second run UNcomment this line out
//int *y = new int[N]; //in the second run UNcomment this line out
for (int i = 0; i < N; i++)
{
x[i] = 1;
y[i] = 2;
}
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
currentUsedRAM = info.WorkingSetSize - currentUsedRAM;
std::cout << "Current RAM used: " << currentUsedRAM << "\n";
return 0;
}
Что я совсем не понимаю, когда запускаю приведенный выше код, вывод таков: Current RAM used: 0
в то время как я ожидал что-то около 8 МБ, так как я заполнил два 1D int
массивы по 1 миллиону записей каждый. Теперь, если я перезапущу код, но сделаю x
а также y
стали динамически распределяемыми массивами, теперь вывод будет, как и ожидалось: Current RAM used: 8007680
,
Это почему? Как заставить это обнаруживать использование памяти в обоих случаях?
Компилятор оптимизировал ваш код. Если факт, для вашего первого запуска, ни х или у не выделяется. Учитывая, что есть видимый побочный эффект: возвращаемое значение GetProcessMemoryInfo, эта оптимизация кажется странной.
В любом случае, вы можете предотвратить это, добавив некоторый другой побочный эффект, такой как вывод суммы каждого элемента этих двух массивов, который защитит сбой.
Происходит выделение памяти для локальных объектов с автоматической продолжительностью хранения в начале вмещающего кодового блока и освобождается в конце. Таким образом, ваш код не может измерить использование памяти для какой-либо переменной длительности автоматического sotrage в main (ни для моего фрагмента удаленного кода, которого я не боялся). Но вещи отличаются для тех объектов с динамической длительностью хранения, они распределяются по запросу.
Я разработал тест, который включает отторжение для обсуждения в области комментариев. Вы можете видеть, что использование памяти увеличилось, если программа идет глубже. Это доказательство того, что он учитывает использование памяти в стеке. Кстати, он не учитывает, сколько памяти нужно вашим объектам, а сколько вашей программе.
void foo(int depth, int *a, int *b, uint64_t usage) {
if (depth >= 100)
return ;
int x[100], y[100];
for (int i = 0; i < 100; i++)
{
x[i] = 1 + (a==nullptr?0:a[i]);
y[i] = 2 + (b==nullptr?0:b[i]);
}
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
std::cout << "Current RAM used: " << info.WorkingSetSize - usage << "\n";
foo(depth+1,x,y,usage);
int sum = 0;
for (int i=0; i<100; i++)
sum += x[i] + y[i];
std::cout << sum << std::endl;
}
int main(void)
{
uint64_t currentUsedRAM(0);
PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
currentUsedRAM = info.WorkingSetSize;
foo(0, nullptr, nullptr, currentUsedRAM);
return 0;
}
/*
Current RAM used: 0
Current RAM used: 61440
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 73728
*/
Система выделяет 4 КБ каждый раз, что является размером страницы. Я не знаю, почему он приходит 0, а потом вдруг 61440. Объяснить, как windows управляет памятью, очень сложно и далеко не в моих силах, хотя я уверен в 4k … и что он действительно учитывает использование памяти для переменных с автоматической продолжительностью хранения.
Других решений пока нет …