Означает ли ключевое слово "using", что объект расположен и GC'ed?

c# .net garbage-collection dispose

3150 просмотра

2 ответа

5026 Репутация автора

Сегодня я завел разговор с моей коллегой, которая сказала, что только что узнала причину использования этого usingзаявления.

 //Using keyword is used to clean up resources that require disposal (IDisposable interface). 

 using (StreamReader reader = new StreamReader(@"C:\test.txt")) 
 { 
 string line = reader.ReadLine(); 
 } 

Я указал, что объект помечен как «Может быть утилизирован», но на самом деле не утилизируется и не собирает мусор, если только GC не решит это сделать.

Она ответила, что объект будет автоматически удален после завершения оператора using, поскольку оператор using преобразуется в блок try-catch-finally. Таким образом, объект должен быть расположен в самом конце оператора using.

Я был смущен этим, потому что я знаю, что использование usingоператора не гарантирует, что объект будет собран GC. Все, что происходит, это то, что Dispose()метод будет вызван. GC решает, когда GC это независимо. Но когда она попросила доказательства, я не смог найти ни одного.

Кто-нибудь знает, как это работает и как это доказать?

Автор: now he who must not be named. Источник Размещён: 22.04.2014 07:29

Ответы (2)


41 плюса

52414 Репутация автора

Решение

Вы говорите о двух очень разных вещах.

Объект будет удален, как только usingзакончится -блок. Это ничего не говорит о том, когда это мусор. Единственный раз, когда освобождается память кучи, это когда происходит сборка мусора - что происходит только под давлением памяти (если вы не используете GC.Collectявно).

Удаление объекта просто означает вызов его Disposeметода. Чаще всего это означает освобождение либо дефицитного ресурса, либо собственного ресурса (на практике все дефицитные ресурсы являются собственными - сокеты, файлы, ...). Теперь удобно, что время жизни одноразового объекта в вашем случае ограничено по объему, поэтому теоретически его можно собрать, как только usingзакончится -блок, однако на практике этого не происходит, так как среда выполнения .NET пытается избегать коллекций - они дорогие. Таким образом, пока вы не превысите порог выделения памяти , никакой коллекции не произойдет, даже если у вас в куче мертвый объект.

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

Так что да, она была совершенно права. Дело в том, что IDisposableэто не имеет никакого отношения к сборщику мусора. Утилизация не означает сбор мусора.

Автор: Luaan Размещён: 22.04.2014 07:32

12 плюса

63166 Репутация автора

Она права в денежном usingотчете просто для синтетического сахара try/finally{obj.Dispose();}. usingЭто утверждение гарантирует, что объект будет удален (будет вызван метод Dispose), но он не имеет отношения к сбору мусора.

Взгляните на это заявление о понимании использования

Краткий ответ: Итак, теперь мы знаем, что использование оператора - это просто вызов Disposeи ничего не делает, кроме того, и помните, что Disposeметод не является чем-то особенным, чем любые другие методы. Это просто метод и все. Так что это никак не связано со сборкой мусора. Интересно, что «Сборщик мусора» даже не знает о Disposeметоде или IDisposable.

Надеюсь это поможет

Автор: Sriram Sakthivel Размещён: 22.04.2014 07:33
Вопросы из категории :
32x32