Где можно найти более подробную информацию об утилизации ресурсов COM в .NET? - PullRequest
5 голосов
/ 24 мая 2011

Фон для моего вопроса таков: я конвертирую приложение для обработки сообщений, которое использует множество компонентов COM из VB6 в C #.Многие из компонентов COM в приложении являются детализированными компонентами, которые используются в больших количествах и с частотой в циклах обработки сообщений.Я наблюдаю значительное (и прогрессивно растущее) увеличение использования памяти при обработке набора тестовых сообщений в приложении C # по сравнению с приложением VB6.Я использовал профилировщик памяти в приложении, которое подтвердило, что высокое использование памяти было вызвано живыми экземплярами COM-объектов в неуправляемой куче приложения.Я знаю, что эти компоненты не «просочились» из-за живых ссылок, потому что если я положу GC.Collect () в ядро ​​цикла обработки сообщений, использование памяти будет плоским и почти идентичным приложению VB6 (хотя производительностьужасно ухудшается, как и следовало ожидать).

Я прочитал все, что могу найти на сборщике мусора нескольких поколений в C #, вызываемых оболочках во время выполнения, неуправляемом распределении памяти ресурсов, Marshal.ReleaseComObject (), Marshal.FinalReleaseComObject () и т. д. Ничто из этого не объясняет, почему приложение удерживает работающие COM-объекты в неуправляемой куче, когда соответствующие RCW имеют право на сборку мусора.

В некоторых статьях я видел намеки на возможность того, что фактическая реализация сборщика мусора в C # может включать в себя оптимизации, такие как не выполнение сбора всех подходящих объектов в конкретном поколении.Если бы это или что-то подобное было правдой, это могло бы объяснить, почему подходящие RCW и их соответствующие COM-объекты не собираются и уничтожаются.Другое объяснение может быть, если уничтожение COM-объекта в неуправляемой куче не связано напрямую с коллекцией соответствующих RCW.Я не нашел ничего такого, что предлагало бы такую ​​степень детализации обработки COM-объектов в .NET.Мне нужно понять это лучше, потому что использование памяти моего приложения в настоящее время недопустимо.Любые указатели или рекомендации будут с благодарностью.

Редактировать: Я должен добавить, что я довольно хорошо знаком с финализаторами (которые не описаны в существующем на RCW) и интерфейсом IDisposable (который RCWsне реализовывать).Насколько я понимаю, Marshal.ReleaseComObject () - это правильный метод явного «удаления» ссылки COM.Я был осторожен, чтобы добавить это утверждение для каждого известного использования COM-объекта в моем приложении, и это не привело к разнице в использовании памяти.

Кроме того, неясно, почему отсутствие кода удаления или завершения может быть проблемой, если добавление явного GC.Collect () не приводит к проблемам с памятью.Ни Dispose (), ни наличие финализатора не приводят к фактической коллекции объектов.Первый позволяет объекту подавить свой этап завершения (если таковой имеется), а второй позволяет очистить неуправляемые ресурсы, ни один из которых не выставлен в RCW.

Ответы [ 2 ]

2 голосов
/ 24 мая 2011

Используйте Финализатор или деструктор для очистки памяти, используемой объектами COM.

http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx

В качестве альтернативы, если выЕсли вы хотите немедленно очистить объекты, вы можете реализовать IDispose и использовать в своем коде оператор using, который создает экземпляр COM-объекта.

2 голосов
/ 24 мая 2011

Правильно ли вы реализуете IDisposable в классах, которые создают экземпляры ваших COM-объектов?

Вам необходимо реализовать IDisposable и утилизировать ваши COM RCW в методе Dispose (). Тогда весь код, который создает экземпляры классов, реализующих IDisposable, должен вызывать его либо явно, либо с помощью оператора using (), например:

var first = new DisposableObject();
...
first.Dispose();

и

using(var first = new DisposableObject())
{
   ...
}

IDisposable - единственный способ заставить CLR своевременно утилизировать эти объекты и убедиться, что вы теряете ссылки COM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...