2010-07-25 2 views
0

У меня есть управляемое оболочкой приложение (.net) через COM-компонент (созданный с помощью vb6), где компонент Com также использует собственную C++ dll.Управляемое + неуправляемое приложение вызывает утечку памяти

Приложение работает как фоновый процесс и должно работать непрерывно 24 X 7. Приложение работает нормально в течение определенного времени, но через некоторое время оно сработает. Возможными причинами может быть утечка мотора в C++ dll или com component. Существует много кода для dll COM и C++.

Поскольку я не знаком с com и C++, я пытаюсь решить проблему из управляемого приложения. Я думаю, что для решения этого: если управляемое приложение начнет потреблять много памяти, я перезапущу управляемое приложение.

1) Как мы можем программно контролировать общую память, используемую приложением (управляемый + неуправляемый).

2) Перезапустив управляемое приложение, также освободите неуправляемые ресурсы.

3) Есть ли другой альтернативный подход.

4) что является лучшим средством отладки для мониторинга управляемого приложения, которое также использовало неуправляемые ресурсы.

Если я не ясно в своем объяснении, то спросите меня снова.

Любая помощь будет принята с благодарностью.

ответ

1

Как мы можем программно контролировать общую память, используемую приложением (управляемый + неуправляемый).

Использование счетчиков производительности. В разработке/тестировании проще всего использовать PerfMon для сбора данных в фоновом режиме (с использованием набора данных), а затем проанализировать результаты в Excel или аналогичные.

Если вам необходимо продолжить использование этого продукта, приложение может самостоятельно считывать счетчики производительности (используя System.Diagnostics.PerformanceCounter и связанные классы).

2) Перезапустив управляемое приложение, также освободите неуправляемые ресурсы.

Да.

3) Есть ли другой альтернативный подход.

Да: исправить проблему.

Если COM-компонент или библиотека C++ действительно протекают, то это действительно необходимо устранить (и если ранее использовались только для короткоживущих процессов, утечка могла быть там в течение длительного времени).

Возможно, вы столкнетесь с взаимодействием управляемой кучи .NET и GC с использованием встроенной кучи. Управляемый GC работает, когда есть давление памяти (то есть в противном случае нужно было бы получить больше памяти для завершения процесса распределения). Если управляемая оболочка не выделяет память (или не много), нет никакой причины для ее запуска GC. Когда вы ссылаетесь на COM-компоненты.NET эта ссылка хранится в собственном типе-оболочке, эта обертка освобождает экземпляр COM (высвобождая последний подсчитанный ссылочный номер COM), когда он собирается GC.

Итак, если GC не запускается, то компоненты COM не будут освобождены. Все, что требуется, - для экземпляров COM использовать значительный объем памяти, и общая фиксация памяти процесса может начать расти.

Существует три подхода (в уменьшении предпочтения):

  1. использовать метод на экземпляре COM, чтобы освободить его использование памяти (например, рилизинг суб-объекты), если он есть.
  2. Явно освобождаю экземпляры COM-компонента, когда код управления завершен с ними — не дожидаясь GC —, используя Marshal.ReleaseComObject.
  3. Форсировать GC.

# 3 является самым простым и может использоваться для подтверждения этого подхода путем принудительного полного GC после нескольких часов работы (например, по таймеру) и просмотра счетчиков производительности использования памяти. Если это так, продолжайте с # 1 или # 2.

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

Смежные вопросы