Кажется, что некоторая память оставлена ​​выделенной после malloc () и free () - PullRequest
4 голосов
/ 15 ноября 2009

Я новичок в C. Я пытаюсь освоиться с malloc + free. Я запрограммировал следующий тест, но по какой-то причине память не освобождается полностью (top по-прежнему показывает около 150 МБ памяти, выделенной для процесса). Почему это так?

#include <stdio.h>
#include <malloc.h>

typedef struct {
    char *inner;
} structure;

int main()
{
    int i;
    structure** structureArray;

    structureArray = (structure**)malloc(sizeof(structure*)*1000*10000);
    for (i = 0; i < 1000*10000;i++)
    {
        structureArray[i] = (structure*) malloc(sizeof(structure));
        structureArray[i]->inner = (char*) malloc(sizeof(char)*1000*1000*1000);
    }

    printf("freeing memory");
    for (i = 0; i < 1000*10000;i++)
    {
        free(structureArray[i]->inner);
        free(structureArray[i]);
    }
    free(structureArray);

    system("sleep 100");
    return 0;
}

corefponding Makefile:

all: test.c
    gcc -o test test.c
    ./test &
    top -p `pidof ./test`
    killall ./test

Ответы [ 3 ]

11 голосов
/ 15 ноября 2009

top сообщит вам количество физической памяти, выделенной вашему процессу. Виртуальная память - это абстракция поверх физической памяти, и malloc / free обеспечивают абстракцию поверх этого.

malloc резервирует место в куче вашей программы. Куча - это просто область виртуального адресного пространства вашей программы, используемая для временного хранения. Когда вы звоните malloc больше, куча расширяется с помощью системного вызова brk. Однако, хотя виртуальный размер вашей кучи увеличивается, физическая память фактически не назначается до тех пор, пока вы не выполните чтение или запись в свою вновь выделенную память. Например, поскольку вы никогда не выполняете запись в память, выделенную для полей inner ваших записей, эти выделения не будут занимать никакой физической ОЗУ.

free просто освобождает части кучи, выделенной malloc. Это не обязательно уменьшает виртуальный размер кучи, поэтому физическая память, связанная с ней, может быть не освобождена. Вот почему вы не видите сокращения использования физической памяти.

6 голосов
/ 15 ноября 2009

Управление памятью в Unix лениво, освобождение памяти процесса не гарантируется, если это кому-то действительно не нужно. Вот хорошая статья.

Также я бы порекомендовал вам проверить результаты malloc (), вы определенно обнаружите, что, по крайней мере, некоторые из них не удалось.

3 голосов
/ 15 ноября 2009

Возможно, что-то из-за того, что вы выделяете порядка 10000000000000000 байт (1000 * 10000 *1000* 1000 * 1000) = ~ 10000000000 Мбайт = 10000000 Гбайт, что несколько раз оборачивает вашу системную память.

...