2015-05-29 2 views
9

Известно, что сборщик мусора .NET не просто «удаляет» объекты в куче, но также борется с фрагментацией памяти, используя уплотнение памяти. Насколько я понимаю, в основном память копируется на новое место, а старое место в какой-то момент удаляется.Как среда выполнения .NET перемещает память?

Мой вопрос: как это работает?

Что мне больше всего любопытно, так это то, что GC работает в отдельном потоке, что означает, что объект, над которым мы работаем, может быть перемещен GC , пока мы выполняем наш код.

Технические детали вопроса

Для иллюстрации, позвольте мне объяснить, на мой вопрос более подробно:

class Program 
{ 
    private int foo; 
    public static void Main(string[] args) 
    { 
     var tmp = new Program(); // make an object 
     if (args.Length == 2) // depend the outcome on a runtime check 
     { 
      tmp.foo = 12;  // set value *** 
     } 
     Console.WriteLine(tmp.foo); 
    } 
} 

В этом небольшом примере мы создаем объект и установить простую переменную на объект. Пункт «***» имеет значение для вопроса: если адрес «tmp» перемещается, «foo» будет ссылаться на что-то неправильное, и все сломается.

Мусороуборочный комбайн работает в отдельной резьбе. Насколько я знаю, «tmp» можно перемещать во время этой инструкции, а «foo» может привести к неправильному значению. Но как-то происходит волшебство, и это не так.

Что касается дизассемблера, я заметил, что собранная программа действительно имеет адрес «Foo» и двигается в значении '12:

000000ae 48 8B 85 10 01 00 00 mov   rax,qword ptr [rbp+00000110h] 
000000b5 C7 40 08 0C 00 00 00 mov   dword ptr [rax+8],0Ch 

я более или менее ожидал увидеть косвенную указатель здесь, который может быть обновлен, но, по-видимому, GC работает умнее этого.

Кроме того, я не вижу ни одной синхронизации потоков, которая проверяет, был ли объект перемещен. Итак, как GC обновляет состояние в исполняемом потоке?

Итак, как это работает? И если GC не перемещает эти объекты, что такое «правило», которое определяет, не перемещать или не перемещать объекты?

+0

Обратите внимание, что в старых версиях .NET использовался «стоп-мир» GC, поэтому управляемые потоки, где были остановлены, выполнены GC, управляемые потоки возобновились. – xanatos

+0

Знаете ли вы, что GC только возобновляет данные, когда ваш экземпляр «Программы» выходит за рамки? До тех пор, пока ваше приложение работает, вы всегда будете иметь правильное значение для 'foo'. – HimBromBeere

ответ

5

.NET GC является (по крайней мере частично) GC «stop-the-world»: он останавливает управляемые потоки, прежде чем выполнять свою работу, выполняет свою работу, а затем перезапускает управляемые потоки.

«Рабочая станция» GC может быть одновременно (так частично не остановить-мир), но обратите внимание на https://msdn.microsoft.com/library/ee851764.aspx.

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

Обратите внимание, что со всеми GC, gen0 и gen1 всегда являются стоп-миром. Таким образом, они могут без проблем перемещать блоки памяти. Только gen2 можно сделать в фоновом режиме с помощью некоторых GC с некоторыми конфигурациями (это link, информация немного фрагментирована по всей странице), поэтому всегда есть момент «мир-остановился», где память, которая была освобожденные могут быть уплотнены.

+0

Обратите внимание, что параллельный GC был фактически заменен «фоновым» GC, начиная с .Net 4. [Некоторые подробности здесь] (https://msdn.microsoft.com/en-us/library/ee787088%28v=vs.110%29 .aspx) –

+0

@MatthewWatson И с 4.5 даже на сервере есть «фоновый» GC. Все еще gen0 и gen1 всегда являются «стоп-миром». Только gen2 работает из другого потока (-ов) – xanatos

+0

@xanatos Это означало бы, что когда «останавливая мир», вы точно знаете, где находится счетчик программ, какие местные жители находятся в регистрах, какие местные жители есть где-то и т. Д. После GC вы продолжаете восстанавливаться все это (и т. д.) - еще хуже: вы делаете все это на другом процессоре, чем там, где вы сейчас работаете? Я даже не знаю, с чего начать, если бы я хотел реализовать это ... Как ты делаешь что-то подобное? – atlaste

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