2014-02-19 5 views
3

Мне задавали этот вопрос, и хотя я считаю, что знаю ответ, я считаю, что должен быть на 100% уверен, что начну распространять дезинформацию!Не освобождаемые ресурсы освобождаются при сборе мусора?

У меня есть этот объект:

public class MyObj(){ 
    private SqlConnection conn; 

    public MyObj(string connString){ 
     var stream = File.Open(@"c:\\file.txt"); 
     conn = new SqlConnection(connString); 
    } 
} 

Когда этот объект создан, дескриптор файла, связанные с файлом, и подключение к базе данных создаются. Ни один из них не имеет Dispose.

Когда этот объект выходит из сферы действия и в конечном итоге собирает мусор, эти два ресурса затем освобождаются или остаются в памяти?

+0

Обратите внимание, что 'private File file;' составлен код, System.IO.File является статическим. –

+0

Yikes, еще рано здесь! Код образца был отредактирован. –

+0

Новый код имеет новые проблемы, но неважно. –

ответ

2

Когда этот объект выходит из сферы действия и в конечном итоге собирает мусор, эти два ресурса затем освобождаются или остаются в памяти?

Обычно некоторые типа - часто несколько скрыты от общественности API - имеет ручку на родном ресурсе, возможно, через SafeHandle, и это то, что в конечном итоге освобождая ресурс. Это возможно, чтобы написать код, который этого не делает, конечно, и в этом случае собственные ресурсы будут выпущены только на выходе процесса через обычную очистку ОС, но я ожидаю, что любые API-интерфейсы, предоставленные Microsoft правильная вещь.

Конечно, вы все равно должны распоряжаться ресурсами явно :)

0

Короткий ответ: Они являются автоматическими отпущена.

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

Никогда не нашел реальной причины, может быть, ошибки в структуре, возможно, что-то связано с ресурсом ОС, но я могу сказать, что 99,99% времени вы можете освободиться от беспокойства об этом на C#.

+0

Утечки памяти обычно не сильно связаны с Dispose и ресурсами. –

+0

В общем, вы правы, но для этой конкретной проблемы явный вызов GB исправил проблему. Это было много лет назад с базой 1.1.4322 – jean

1

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

Когда этот объект выходит из сферы действия и в конечном итоге собирает мусор, эти два ресурса затем освобождаются или остаются в памяти?

Да, неуправляемые ресурсы, в конечном счете, будут освобождены от сборщика мусора, который вызывает финализации объекта.

Как вы знаете, оставляя его сборщику мусора для очистки неуправляемых ресурсов, как правило, плохо. Если вы откроете и прочитаете файл, вы предпочтете, чтобы файл был закрыт и доступен другим процессам, когда чтение завершилось вместо этого в какое-то случайное время, когда сборщик мусора решает освободить теперь неиспользуемый файл-объект.

.NET предоставляет интерфейс IDisposable, позволяющий детерминированный выпуск неуправляемых ресурсов.Когда вы удаляете объект FileStream, основной неуправляемый дескриптор файла освобождается, и файл закрывается.

Важной частью реализации интерфейса IDisposable является то, что если неуправляемый ресурс освобождается по вызову Dispose, то объект больше не нуждается в доработке. Вот почему вы видите вызов GC.SuppressFinalize(this), когда объект реализует IDisposable и имеет финализатор. Избегание финализации - это хорошая вещь, чтобы уменьшить количество ресурсов, которые должен использовать сборщик мусора. Кроме того, финализаторы работают в жестких ограничениях, установленных сборщиком мусора, поэтому их лучше избегать.

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

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