2012-02-07 2 views
4

Я бег следующего кодакогда .net сборщик мусора не компактен gc heap?

 StringBuilder sb = new StringBuilder(); 
     Stack stack = new Stack(); 
     SynchronizationContext sc = new SynchronizationContext(); 

     GC.Collect(); 
     Console.WriteLine("GC. First Execution."); 

     stack = null; 

     GC.Collect(); 
     Console.WriteLine("GC. Second Execution."); 

     GC.Collect(); 
     Console.WriteLine("GC. Third Execution."); 

При отладке этого кода с SOS я вижу, что после первого исполнения GC адресов следующие:

!dso 
... 
0239b5f8 System.Threading.SynchronizationContext 
0239b5a8 System.Collections.Stack 
0239b560 System.Text.StringBuilder 
... 

После второго исполнения нет «стек» объекта куча, но другие адреса:

!dso 
... 
0239b5f8 System.Threading.SynchronizationContext 
0239b560 System.Text.StringBuilder 
... 

Таким образом, объект «стек» был собран, но подкожно (SynchronizationContext) объект не был reloca в памяти для уплотнения. У нас есть зазор в памяти

!do 0239b5a8 
Free Object 
Size:  80(0x50) bytes 

После третьего выполнения ситуация такая же.

Почему это происходит? Почему «компактная» операция не выполняется в этом случае?

спасибо.

+0

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

+0

Спасибо. Вы имеете в виду объект «приколотый»? – user1194191

+0

Я попытался использовать пользовательский объект Foo для SynchronizationContext - это одно и то же. Объект Foo не заменяется в памяти на уплотнение кучи. – user1194191

ответ

3

GC является ленивым, чтобы быть эффективным. Это фактически не будет бесплатным или, как вы говорите, «компактным», пока это не понадобится. Объект был перемещен в очередь размещения.

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

+0

Роб, спасибо. Но объект 'stack' свободен (очищается), как мы видим. Вопрос в том, почему объект «sc» не принял его адрес 0239b5a8 – user1194191

+0

Вы установили объект 'stack' как объект 'null'. Фактически это не значение null, а теперь ссылка на нулевой объект. Таким образом, идентификатор «stack» теперь ссылается на системный объект с именем null. –

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