Подтвердить что ты не робот

Соответствует ли ключевое слово "использование" объекту и GC'ed?

Сегодня я поговорил с моим коллегой, который сказал, что она только что узнала причину использования инструкции 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 переводится в блок try-catch-finally. Таким образом, объект должен располагаться в самом конце инструкции using.

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Взгляните на Understanding-the-using-statement

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

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