2013-04-28 2 views
0

Я вручную скопировать меньший массив в больший массив:Копирование массива/Список без запуска GC

T is constrained to class, new() 

Почему этот триггер ОГО? Является ли присваивание новому массиву не ссылкой? Почему старые элементы старого массива все еще собирают мусор? Действительно ли назначение внутри первого цикла копирует их?

public void Resize() 
{ 
    T newArray = new T[oldArray.Length * 2]; 

    for (int i = 0; i < oldArray.Length; i++) 
    { 
     newArray[i] = oldArray[i]; 
    } 

    for (int i = oldArray.Length; i < newArray.Length; i++) 
    { 
     // Assign new elements to the new array 
    } 

    oldArray = newArray; 
} 
+1

Вы уверены, что сборщик мусора 'oldArray' не собран, а не его содержимое? –

ответ

3

Как только вы называете new создать ссылку на новый объект в куче. Когда вы назначаете ссылку

oldArray = newArray; 

обе ссылки указывают на новый объект. Если ссылок на объект oldArray больше нет, он имеет право на сбор мусора.

Для reference:

Высвобождение памяти. Механизм оптимизации сборщика мусора определяет наилучшее время для выполнения коллекции на основе произведенных распределений. Когда сборщик мусора выполняет сборку, он освобождает память для объектов, которые больше не используются приложением. Он определяет, какие объекты больше не используются, исследуя корни приложения. Каждое приложение имеет набор корней. Каждый корень либо относится к объекту в управляемой куче, либо имеет значение null. К корням приложения относятся глобальные и статические указатели объектов, локальные переменные и параметры ссылочных объектов в стеке потока, а также регистры процессора. Сборщик мусора имеет доступ к списку активных корней, которые компилятор точно в срок (JIT) и среда выполнения поддерживают. Используя этот список, он исследует корни приложения, и в этом процессе создается граф, содержащий все объекты, доступные из корней. Объекты, которые не находятся на графике, недоступны из корней приложения. Сборщик мусора рассматривает недостижимые объекты мусора и освобождает выделенную им память. Во время сбора сборщик мусора проверяет управляемую кучу, ища блоки адресного пространства, занятые недоступными объектами. Когда он обнаруживает каждый недостижимый объект, он использует функцию копирования памяти для уплотнения достижимых объектов в памяти, освобождая блоки адресных пространств, выделенных для недоступных объектов. После того, как память для достижимых объектов была уплотнена, сборщик мусора делает необходимые корректировки указателя так, чтобы корни приложения указывали на объекты в их новых местоположениях. Он также позиционирует указатель управляемого кучи после последнего достижимого объекта. Обратите внимание, что память уплотняется только в том случае, если коллекция обнаруживает значительное количество недостижимых объектов. Если все объекты в управляемой куче выживают в коллекции, тогда нет необходимости в уплотнении памяти. Для повышения производительности среда выполнения выделяет память для больших объектов в отдельной куче. Сборщик мусора автоматически освобождает память для больших объектов. Однако, чтобы избежать перемещения больших объектов в памяти, эта память не уплотняется.

+0

Так что мой вопрос в том, что * точно * получает сбор мусора? Элементы - это все ссылки нового массива. Что именно получается из старого массива? – RecursiveCall

+0

Если в вашем массиве единственные ссылки на ваши элементы массива, они потеряют ссылки вместе с массивом. Итак, все они ... –

+1

Но из кода старые элементы не должны собираться с мусором, так как на них ссылается новый массив. – Rok

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