2015-09-05 5 views
1

После некоторых тестов с помощью диспетчера задач я понял одну вещь о gcnew - память, выделенная для локальных переменных, остается выделенной, даже если элемент управления выходит из функции, и перераспределяется только тогда, когда управление повторно входит в эту функцию, поэтому я вхожу в недоумение, как освободить память. Вот несколько примеров проблемы:Как освободить память, выделенную gcnew?

void Foo(void) 
{ 
    System::Text::StringBuilder^t = gcnew System::Text::StringBuilder(""); 
    int i = 0; 
    while(++i < 20000000) t->Append(i); 
    return; 
} 

Как я уже говорил, память для переменной t остается после ухода Foo(), delete не работают, как это работает для new и вызова Foo() один раз, только дает мне бессмысленную выделенную память.

+1

Почему вы выделили его динамически в первую очередь? – emlai

+1

Почему, черт возьми, вы использовали управляемый C++ в первую очередь? это как есть торт без сахара. –

+0

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

ответ

0

Это gcnew, что означает сбор собранных мусора. Он будет удален и освобожден резьбой GC

0

Ваша функция использует память для кода и данных. Код является фиксированной суммой и будет использоваться при загрузке библиотеки или программы. Данные используются только при выполнении функции.

Данные, используемые программой, являются либо статическими, либо динамическими. Статические данные выкладываются компилятором и в основном эквивалентны коду (за исключением того, что он может быть помечен как неисполняемый и/или только для чтения, чтобы предотвратить несчастные случаи). Динамические данные являются временными и выделяются из стека или кучи (или регистров процессора).

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

Имейте в виду, что когда программа запрашивает диапазон адресов, это просто сигнализирует операционной системе, что использовать этот адрес для чтения данных, записи данных и/или выполнения кода можно. Пока он на самом деле ничего там не накладывает, на систему нет нагрузки. Также имейте в виду систему виртуальной памяти, операционная память эффективно распределяется по файлу/устройству (жесткому диску) подкачки с оптимизацией, особенно с использованием ОЗУ для кэширования, копирования на запись и многих других методов. (Данные, записанные в адрес памяти, никогда бы не сделать это в файл подкачки, но это до операционной системы.)


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

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

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

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

  1. Коллекция мусора побежал найти недостижимых объектов.
  2. Куча уплотнена.
  3. Уменьшение кучи было уменьшено.

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

Смежные вопросы