Высвободите средства в.Net C#

Я плохо знаком с C# и.NET, и читал вокруг об этом.

Я должен знать, почему и когда я должен высвободить средства? Разве сборщик "мусора" не заботится обо всем? Когда я должен реализовать IDisposable, и как это отличается от деструктора в C++?

Кроме того, если моя программа является довольно небольшой т.е. экранная заставка, я должен заботиться о высвобождении средств?

Спасибо.

13
задан zaidwaqi 4 May 2010 в 09:13
поделиться

6 ответов

По сути, вам нужно беспокоиться об освобождении ресурсов для неуправляемого кода - всего, что находится за пределами .NET framework. Например, подключение к базе данных или файл в ОС.

Сборщик мусора работает с управляемым кодом - кодом в .NET framework.

Даже небольшому приложению может потребоваться высвободить неуправляемые ресурсы, например, оно может выполнять запись в локальный текстовый файл. Когда вы закончите с ресурсом, вам нужно убедиться, что вызывается метод Dispose объекта. Оператор using упрощает синтаксис:

using (TextWriter w = File.CreateText("test.txt"))
{
    w.WriteLine("Test Line 1");
}

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

Если вы создаете свои собственные классы, которые необходимо правильно удалить, вам нужно будет самостоятельно реализовать интерфейс IDisposable и шаблон Dispose. В простом приложении вам, вероятно, не понадобится это делать, если вы сделаете , этот будет хорошим ресурсом.

2
ответ дан 1 December 2019 в 22:57
поделиться

Сборщик мусора знает только о памяти. Это нормально для памяти, потому что один бит памяти почти так же хорош, как и любой другой, если у вас его достаточно.(Это все согласованность кэша по модулю и т. Д.)

Теперь сравните это с дескрипторами файлов. В операционной системе может быть достаточно места для выделения дополнительных дескрипторов файлов, но если вы оставили дескриптор открытым для определенного файла, никто другой не сможет открыть этот конкретный файл для записи. Вы должны сообщить системе, когда вы закончили с дескриптором, обычно закрывая соответствующий поток, как только вы закончите, и сделать это таким образом, чтобы закрыть его, даже если возникнет исключение. Обычно это делается с помощью оператора using , который похож на try / finally с вызовом Dispose в блоке finally.

Деструкторы в C ++ очень отличаются от финализаторов .NET, поскольку деструкторы C ++ детерминированы - они автоматически вызываются, например, когда соответствующая переменная выпадает из области видимости. Финализаторы запускаются сборщиком мусора в какой-то момент после того, как на объект больше не ссылаются какие-либо «живые» объекты, но время непредсказуемо. (В некоторых редких случаях это может никогда не произойти.)

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

15
ответ дан 1 December 2019 в 22:57
поделиться

Вам не нужно освобождать память в управляемых объектах, таких как строки или массивы, - это обрабатывается сборщиком мусора.

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

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

Также полезно знать об операторе using .

1
ответ дан 1 December 2019 в 22:57
поделиться

Ресурсы бывают двух видов - управляемые и неуправляемые. Управляемые ресурсы будут очищены сборщиком мусора, если вы позволите ему, то есть если вы освободите любую ссылку на объект. Однако сборщик мусора не знает, как освободить неуправляемые ресурсы, которые хранятся в управляемом объекте - например, дескрипторы файлов и другие ресурсы ОС.

IDisposable является наилучшей практикой, когда есть управляемый ресурс, который нужно освободить в кратчайшие сроки (например, соединение с базой данных), и жизненно важен, когда есть неуправляемые ресурсы, которые необходимо освободить. Типичный шаблон:

public void Dispose()
protected void Dispose(bool disposing)

Обеспечивает освобождение неуправляемых ресурсов с помощью метода Dispose или финализации объекта.

2
ответ дан 1 December 2019 в 22:57
поделиться

Сборщик мусора освобождает ПАМЯТЬ и очищает - посредством удаления - элементы, которые он удаляет. НО: ЭТО делает это только тогда, когда у него нехватка памяти.

Это серьезный идиотизм для ресурсов, и я, возможно, захочу их явно выпустить. Например, сохранение в файл должно: открыть файл, записать данные и - закрыть файл, чтобы он мог быть скопирован пользователем, если он хочет, БЕЗ ожидания, пока сборщик мусора вернется и освободит память. для файлового объекта, что может не происходить в течение нескольких часов.

0
ответ дан 1 December 2019 в 22:57
поделиться

Вам нужно беспокоиться только о ценных ресурсах. Большинство объектов, которые вы создаете при программировании, не попадают в эту категорию. Как вы говорите, сборщик мусора позаботится о них.

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

0
ответ дан 1 December 2019 в 22:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: