2010-04-29 2 views
2

Эта особая проблема сводит меня с ума. Интересно, испытывал ли кто-нибудь подобную проблему. Если я загружаю рабочий процесс, выгружаю его и выполняю снимок памяти, тогда результат предсказуем - мой рабочий процесс больше не находится в памяти. Однако, если я загружаю рабочий процесс и устанавливаю действие PersistableIdle в PersistableIdleAction.Unload, и пусть рабочий процесс не работает, рабочий процесс остается в памяти, даже если срабатывает действие Unload.Утечка памяти при использовании Workflow 4.0 SqlWorkflowInstanceStore и PersistableIdleAction.Unload

Я использовал ANTI Memory Profiler для отладки этой проблемы. Это выводимый граф объекта, показывающий, что внутренний объект висит на моем экземпляре рабочего процесса.

alt text http://www.rohland.co.za/wp-content/uploads/2010/04/Workflow_retention_graph.png

Может ли кто-то проверить эту проблему? Мой код сводится к следующему:

  1. Создать SqlWorkflowInstanceStore и владелец замка установки ручка
    - На данный момент я беру снимок памяти
  2. Создание экземпляра Workflow1
  3. Установить действие PersistableIdle
  4. Примените instancestore к Workflow1
  5. Настройка обработчиков событий события для Idle, Unload, UnhandledException и т. Д.
  6. Сохранять рабочий процесс instanc е
  7. Запустите экземпляр рабочего процесса
  8. Дождитесь экземпляра на холостом ходу (из-за активности задержки)
  9. Убедитесь, что действие Разгрузка обжигают
    - На данный момент я беру второй снимок памяти

Из приведенного выше изображения видно, что единственным объектом, ссылающимся на Workflow1, является некоторый результат обработки внутренних обработчиков событий, который у меня нет в распоряжении.

Любые подсказки?

+0

Если вы хотите воспроизвести это поведение, откройте следующий образец, предоставленный библиотекой образцов WCF и WF из Microsoft - WF \ Basic \ Execution \ ControllingWorkflowApplications \ CS. Если я открою приложение и запустил несколько экземпляров рабочих процессов, они завершатся, но память не будет выпущена. – Rohland

ответ

0

Кажется, что интересная ошибка? У меня нет профилировщика, который вы упомянули, так что пару вопросов.

  • Ваше исследование связано с некоторыми значительными проблемами использования памяти?

  • Насколько вы уверены в том, что действие разгрузки действительно завершено во время профилирования (vs должно произойти асинхронно и т. Д.)?

  • Кажется, что асинхронная цепь в порядке, но объект TdsParserStateObject, вероятно, будет утечка реального объекта. Я замечаю, что класс имеет метод Dispose(), но не реализует IDisposable. Поэтому другая идея заключается в том, что Dispose() используется для ручного «сброса» или «повторного использования» объекта в какой-то определенный момент времени, но этот момент времени оказывается «еще не (время разгрузки), а позже», например. ленивая утилизация. Ваш профилировщик позволяет вам увидеть, увеличивается ли количество TdsParserStateObjects с течением времени, чтобы указать на настоящую утечку? В отличие от «всего лишь конечного числа объектов, поэтому не настоящая утечка».

+0

После повторного тестирования сценария (я загрузил и работал без работы в 5000 рабочих процессов) кажется, что со временем (через несколько минут после того, как рабочие процессы простаивают) объекты рабочего процесса в памяти освобождены. Возможно, вы ошибаетесь в своем предположении, что объекты перерабатываются лениво. Мне интересно узнать, что вызывает это событие. – Rohland

+0

Это может быть функция класса SqlClient, вы можете попробовать спросить на форуме http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/threads –