Распределение памяти и использование памяти процесса

Я хотел бы понять, почему данные, которые динамически распределяются при многократном вызове, используют столько памяти, сколько указано в коде или выделяется с помощью одного вызова 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 раз, а на втором только один раз. Память, которую вы намереваетесь использовать, та же самая, но информация, которую система должна "запомнить", отсутствует.

Другие вопросы по тегам