В C ++, когда процесс сохраняет выделенную память, даже если вызывается delete? - PullRequest
4 голосов
/ 11 августа 2009

Я хотел бы понять, что происходит во время выполнения GCC в следующей ситуации.

У меня есть программа на C ++, которая выделяет много блоков памяти и затем удаляет их. Что удивительно, так это то, что память не возвращается операционной системе во время выполнения GCC. Вместо этого он все еще хранится в моей программе, я полагаю, на случай, если я захочу выделить подобные куски памяти в ближайшем будущем.

Следующая программа демонстрирует, что происходит:

#include <iostream>
using namespace std;

void pause1()
{
    cout << "press any key and enter to continue";
    char ch;
    cin >> ch;
}

void allocate(int size)
{
    int **array = new int*[size];
    for (int c = 0; c < size; c++) {
        array[c] = new int;
    }
    cout << "after allocation of " << size << endl;
    for (int c = 0; c < size; c++) {
        delete array[c];
    }
    delete [] array;
}

int main() {
    cout << "at start" << endl;
    pause1();
    int size = 1000000;
    for (int i = 0; i < 3; i++) {
        allocate(size);
        cout << "after free" << endl;
        pause1();
        size *= 2;
    }
    return 0;
}

Я проверяю объем памяти, удерживаемый процессом при каждой паузе (когда он вообще не должен удерживать память), выполняя «ps -e -o vsz, cmd».

Сумма, удерживаемая процессом при каждой паузе, равна:

  2648kb - at start  
 18356kb - after allocating and freeing 1,000,000 ints  
  2780kb - after allocating and freeing 2,000,000 ints  
 65216kb - after allocating and freeing 4,000,000 ints  

Я работаю на Fedora Core 6 и использую GCC 4.1.1.

Ответы [ 2 ]

11 голосов
/ 11 августа 2009

Распределитель памяти, используемый библиотекой C, распределяет содержимое различными способами в зависимости от размера порции. Страницы не всегда возвращаются в ОС при освобождении памяти, особенно если вы выполняете много небольших выделений.

Память может быть возвращена ОС только постранично, а не для небольших выделений.

Если вам действительно нужно это знать, изучите исходный код библиотеки C и установите его и т. Д.

В C ++ вы можете переопределить распределители для контейнеров, чтобы сделать ваше собственное управление памятью - тогда вы можете делать все, что захотите (например, mmap / dev / zero или что-то еще)

5 голосов
/ 11 августа 2009

Зависит от того, что, как правило, если вы используете Linux-блок, основной malloc начнет распределять содержимое в куче, и он будет расти, однако, если вы освободите какой-то большой внутренний блок, он не сможет ничего освободить до самого верха. часть кучи освобождается, поскольку единственное, что он может сделать, это увеличить или уменьшить кучу.

Итак, если вы выделите огромный кусок, позже меньший кусок, а затем освободите свой кусок ошибки, может случиться так, что они будут упорядочены по порядку, и пока вы не освободите меньший кусок, ваш процесс не сможет уменьшить кучу размер.

В вашем текущем примере может случиться так, что первые освобождаемые вами файлы не ждут следующих распределений, а затем они не могут быть освобождены, потому что у вас есть что-то, выделенное поверх него. Или, возможно, он не начнет освобождаться до заданного объема памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...