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

StackOverflow https://stackoverflow.com/questions/492984

Вопрос

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

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

Это было полезно?

Решение

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


Редактировать:Ответ на вопрос в комментарии (слишком длинный для комментария)

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

Другие советы

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

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

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

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

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

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

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

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

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

Короткий ответ был бы таким: все, что вы получаете за спиной CLR (в операционной системе), может быть названо как 'родной'.

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

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

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

Теперь есть 2 способа запустить очистку объекта.

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

В обоих случаях неуправляемые ресурсы должны быть освобождены, иначе "УТЕЧКИ!", "СБОИ!" и т. Д. всплывают на поверхность.Но вы должны пытаться очистить управляемые ресурсы только в первом случае Dispose().В последнем случае / финализатор - среда CLR, возможно, уже доработала и собрала некоторые из ваших участников, поэтому вам не следует обращаться к ним (среда CLR не гарантирует порядок, в котором завершается объектный граф.) Следовательно, вы избегаете проблем, защищая свою управляемую очистку с помощью if (AmIBeingCalledFromDispose) проверка охраны

HTH

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top