Как мы можем программно контролировать общий объем памяти, используемой приложением (управляемый + неуправляемый).
Использовать счетчики производительности.В разработке / тестировании проще всего использовать PerfMon
для сбора данных в фоновом режиме (с использованием набора сбора данных), а затем анализировать результаты в Excel или аналогичном формате.
Если вам необходимо продолжить это в производственном использовании,приложение может считывать счетчики производительности самостоятельно (используя System.Diagnostics.PerformanceCounter
и связанные классы).
2) Перезапуск управляемого приложения также освобождает неуправляемые ресурсы.
Да.
3) Есть ли другой альтернативный подход.
Да: устранить проблему.
Если компонент COM или библиотека C ++ действительно имеют утечки, то их действительно необходимо исправить (и если ранее они использовались только для недолговечных процессов, утечка могла быбыл там долгое время).
Возможно, вы столкнулись с взаимодействием управляемой кучи .NET и GC с использованием собственной кучи.Управляемый GC запускается, когда есть нехватка памяти (то есть в противном случае потребуется больше памяти для процесса, чтобы завершить выделение).Если управляемая оболочка не выделяет память (или не сильно), то нет причин для ее запуска GC.Когда вы ссылаетесь на компоненты COM из .NET, ссылка сохраняется в собственном типе оболочки, эта оболочка освобождает экземпляр COM (путем освобождения последней подсчитанной ссылки COM), когда он собирается GC.
Так что еслиGC не запускается, тогда компоненты COM не будут освобождены.Все, что требуется для использования экземплярами COM, - это использовать значительный объем памяти, и общий объем памяти процесса может начать расти.
Существует три подхода (в порядке убывания предпочтений):
- Используйте метод в экземпляре COM, чтобы освободить его использование памяти (например, высвободить подобъекты), если он есть.
- Явно освободите экземпляры COM-компонента, когда управляемый код закончил с ними - не ждитеGC - использование
Marshal.ReleaseComObject
. - Force GC.
# 3 является самым простым и может использоваться для подтверждения этого подхода путем принудительного полногоGC после нескольких часов работы (например, по таймеру) и просмотра счетчиков производительности использования памяти.Если дело обстоит так, переходите к # 1 или # 2.
(Это, по сути, то, что произошло в одном из моих первых проектов .NET, взаимодействие большого количества неуправляемой кучи не было освобождено управляемым экземпляром.это не было собрано из-за недостатка управляемой памяти. Исправление в этом случае заключалось в добавлении дополнительного метода к ключевому компоненту COM для освобождения объектов, которые он держал.)