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

В чем разница между управляемыми и собственными ресурсами при утилизации? (.СЕТЬ)

Я читал статью MSDN о том, как реализовать IDisposable, и я не уверен в различии между управляемыми и родными ресурсами, указанными в статье.

У меня есть класс, который должен располагать 2 своих полей, когда он расположен. Должен ли я относиться к ним как к управляемому (распоряжаться только при утилизации = истинно) или для собственных ресурсов?

4b9b3361

Ответ 1

Управляемый ресурс - это другой управляемый тип, который реализует IDisposable. Вы должны вызвать Dispose() для любого другого типа IDisposable, который вы используете. Родные ресурсы - это что-то вне управляемого мира, например, ручные дескрипторы Windows и т.д.


EDIT: ответьте на вопрос в комментарии (слишком долго для комментария)

Нет, это только управляемый тип. Правильно построенный тип, который не реализует IDisposable, будет обрабатываться сборщиком мусора, и вам не придется ничего делать. Если ваш тип напрямую использует собственный ресурс (например, вызывая библиотеки Win32), вы должны реализовать IDisposable в своем типе и избавиться от ресурсов (ов) в методе Dispose. Если ваш тип использует собственный ресурс, инкапсулированный другим типом, который реализует IDisposable, вы должны вызвать Dispose() для экземпляров этого типа в методе Dispose вашего типа.

Ответ 2

Чтобы добавить немного ответа Брайана и ваш комментарий/вопрос:

Разница между управляемым/неуправляемым ресурсом заключается в том, что сборщик мусора знает об управляемых ресурсах и не знает об неуправляемых ресурсах. Я знаю, что ответ не очень конкретный, но разница огромная.

Чтобы помочь нарисовать линию на песке, это краткая (и, вероятно, небольшая ошибка) версия о том, как GC работает и очищает память:

Сборщик мусора знает обо всех управляемых объектах, но при запуске сборки мусора он не знает, действительно ли какой-либо данный объект все еще используется или может быть выпущен. Он определяет, может ли он очистить объект, сначала пометив все объекты как мусор, а затем перейдя от корня приложения ко всем ссылочным объектам. Каждый объект, имеющий отношение к корню (ссылка, прямая или косвенная), становится помеченной как достижимая и больше не считается мусором. После того, как GC проходит через каждый достижимый объект, он очищает остальное, так как они больше не используются.

Почти во всех случаях, работающих с объектами .NET Framework, вы можете быть уверены, что объекты управляются (.NET предоставляет управляемые обертки почти всех неуправляемых ресурсов, чтобы обеспечить их правильную очистку); другие сторонние компоненты, которые подключаются к API Win32 (или вашим компонентам, которые это делают), являются объектами, которые могут вызывать беспокойство.

Есть некоторые объекты .NET, которые можно считать несколько неуправляемыми. Компоненты библиотеки Graphics - один из примеров.

Большинство "утечек .NET Memory" на самом деле не являются утечками памяти в истинном смысле. Обычно они возникают, когда вы считаете, что удалили объект из использования, но на самом деле объект все еще имеет некоторую ссылку на приложение. Общим примером является добавление обработчиков событий (obj.SomeEvent + = OnSomeEvent -или- AddHandler obj.SomeEvent, AddressOf OnSomeEvent) и не удалять их.

Эти "затяжные ссылки" технически не являются утечками памяти, поскольку ваше приложение по-прежнему технически их использует; однако, если их достаточно, ваше приложение может подвергнуться серьезным последствиям для работы и может проявлять признаки проблем с ресурсами (OutOfMemoryExceptions, неспособные достичь оконных ручек и т.д.).

Я являюсь промежуточным разработчиком .NET и, к сожалению, знаю об этих проблемах из первых рук. Я рекомендую играть с ANTS Profiler, чтобы помочь ознакомиться с затянутыми ссылками (есть бесплатная пробная версия) или если вы хотите получить немного более пристальное исследование с использованием WinDbg и SOS.DLL, чтобы посмотреть на управляемую кучу. Если вы решите изучить последний, я рекомендую прочитать блог Тесса Феррандеза; у нее много отличных уроков и советов по эффективному использованию Windbg.

Ответ 3

Коротким ответом было бы то, что вы делаете за пределами CLR назад (для ОС), чтобы получить его можно назвать " native".

  • неуправляемое распределение памяти. Если вы "обновляете" кусок памяти в управляемом классе CantStayManaged, то CantStayManaged отвечает за освобождение этой памяти (ресурса).
  • обрабатывает файлы, трубы, события, конструкции синхронизации и т.д. - в качестве правила большого пальца, если вы вызываете WinAPI для получения указателей/дескрипторов ресурса, то это "собственные ресурсы"

Итак, теперь у CantStayManaged есть 2 вещи, которые необходимо очистить, прежде чем он предложит adieu.

  • Управляемые: поля пользователя и любые ресурсы, выделенные средой CLR. Обычно это эквивалентно вызову Dispose на объектах-членах "Одноразовые".
  • Неуправляемый: весь подлый низкоуровневый материал, который мы вытаскиваем за его спину.

Есть два способа очистки объекта.

  • Dispose (true) case: Вы вызываете Dispose явно на свой тип. Хороший программист.
  • Dispose (false) case: вы забыли позвонить Dispose, и в этом случае финализатор должен нажать и по-прежнему обеспечить правильную очистку.

В обоих случаях неуправляемые ресурсы должны быть освобождены иначе: "LEAKS!", "CRASHES!" et.all поверхность. Но вы должны только пытаться очистить управляемые ресурсы только в предыдущем случае Dispose(). В последнем случае/финализаторе CLR может быть уже завершена и собрана часть ваших членов, поэтому вы не должны обращаться к ним (CLR не гарантирует порядок, в котором графический объект завершен.) Следовательно, вы избегаете проблем путем охраны ваша управляемая очистка с контрольной проверкой if (AmIBeingCalledFromDispose)

НТН