Распределение памяти и использование памяти процесса
Я хотел бы понять, почему данные, которые динамически распределяются при многократном вызове, используют столько памяти, сколько указано в коде или выделяется с помощью одного вызова malloc
,
Примеры
В качестве примера я сделал следующие два кода на C:
test1.c: int x выделяется сmalloc
int main (void)
{
int *x;
int i, n=1048576; //n=1024*1024;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x = malloc(sizeof(int));
*x=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
Я не использовал здесь бесплатно, чтобы все было просто. Когда программа ожидает взаимодействия, я смотрю на верхнюю функцию в другом терминале, и она показывает мне это:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1384 root 20 0 41300 34076 1300 S 0.0 3.3 0:00.47 test1
test2.c: int x не выделяется динамически
int main (void)
{
int x[1048576]; //x[1024*1024]
int i, n=1048576;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
И сверху показывает мне:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1352 root 20 0 12404 5500 1304 S 0.0 0.5 0:00.05 test2
Я также сделал третий код, который имеет тот же результат, что и test2, где я использовал:
x = malloc(n*sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
Почему такая большая разница в использовании памяти процессами? Это потому, что malloc запрашивает новые страницы памяти и не теряется ли память? Или же malloc
выделяет больше памяти?
test1 использует 3,3% от общей памяти, а test2 использует 0,5%.
Среда:
Я выполняю эти тесты на Centos 5 64 бит в докере.
Память в виртуальной среде:
$ free -m
total used free shared buff/cache available
Mem: 995 98 845 3 51 808
Swap: 1162 194 967
2 ответа
Каждое распределение памяти должно отслеживаться так, чтобы free()
может освободить место для повторного использования. На практике это означает, что выделен минимальный объем памяти; это может быть 8 или 16 байтов для 32-битной программы и 16-32 байта для 64-битной программы (это зависит от системы и используемой версии библиотеки C).
Когда вы выделяете один миллион целых чисел отдельно, каждое из них использует 8-32 байта, так что вы фактически использовали 8-32 МБ памяти. Когда вы выделяете один миллион целых чисел в одном массиве в стеке, вы используете 4 МБ памяти.
Следовательно, вы видите существенную разницу в размере процесса.
Первая программа, разумеется, теряет почти всю память, но это имеет отношение к вопросу, который вы задаете.
Система должна выполнять некоторую служебную работу каждый раз, когда пользователь запрашивает некоторую память. Это следует иметь в виду, когда достаточно просто вызвать free с вашим указателем, чтобы система освободила свою память.
Итак, в первом примере вы запрашиваете память n
раз, а на втором только один раз. Память, которую вы намереваетесь использовать, та же самая, но информация, которую система должна "запомнить", отсутствует.