Проблема с памятью приложения - PullRequest
2 голосов
/ 29 октября 2011

Я создал небольшую службу Windows, которая запускает плагины.

Каждый плагин - это dll, который загружается в отдельный AppDomain с использованием метода CreateInstanceAndUnwrap, и я сохраняю ссылку на AppDomain.

Как только плагин завершает работу, я выключаю AppDomain, созданный для этого плагина. Я использую теневое копирование, чтобы разрешить обновления плагинов, пока они работают в платформе.

Он работал в течение 6 месяцев до последней недели, когда я решил поместить основные функциональные возможности фреймворка также в отдельную DLL и выполнить эту DLL в отдельном AppDomain.

Как это работает прямо сейчас:

  1. Служба Windows запускается.
  2. Ядро ядра загружается и выполняется с использованием CreateInstanceAndUnwrap, которое, в свою очередь, отвечает за запуск плагинов в их отдельных AppDomain

У меня есть несколько разных мест для сборок:

  • Папка с корзиной (в корзине Windows хранятся только библиотеки DLL, используемые этой службой)
  • Core DLLs Folder (здесь находятся основные библиотеки DLL)
  • Папка со ссылками (любые ссылки здесь)
  • Папка плагинов (здесь плагины)

Я разрешаю любые необнаруженные dll, подключаясь к каждому событию OnAssemblyResolve на AppDomain. Это позволяет загружать dll из сети.

Теперь проблема в том, что служба Windows работала в течение одного дня, а память поднялась до 1,5 ГБ. Я создал дамп памяти и похоже, что загруженные модули занимают всего 100 МБ из 1,5 ГБ, поэтому я не знаю, куда уходит вся эта память.

Используя отладку, я увидел предупреждение о фрагментации кучи, но понятия не имею, с чего начать диагностику проблемы. Обычно, когда фреймворк работает в течение дня, он потребляет что-то вроде 100M.

Также это не относится к плагинам; когда я откатил свои изменения в фреймворке, использование памяти стало нормальным, как и раньше. Когда я создаю AppDomain для плагинов, я переключаю basePath и путь к корзине AppDomain на папки CORE и References, в которых находится большинство dll, в надежде, что разрешение сборки вызывается реже.

Я посмотрел журналы Fusion, а также прочитал немного больше о контекстах загрузки, таких как default, from и ничего, но я не уверен, что это правильный путь.

Есть идеи?

1 Ответ

0 голосов
/ 18 ноября 2011

Вы должны попробовать загрузить профилировщик памяти SciNet.Я использовал этот инструмент для диагностики проблем со службами, и он действительно помогает выяснить, где проблема.Доступна бесплатная ознакомительная версия.

Если вы не можете или не хотите устанавливать ее, вы можете попробовать разделить свои плагины на 2 половины и посмотреть, имеют ли они одинаковое поведение в памяти.Вы также можете попробовать вообще без плагинов.

Кроме того, объект сбора мусора в доменах приложений выглядит как tricky .Возможно, вы захотите провести расследование.

...