Утечка памяти при использовании Workflow 4.0 SqlWorkflowInstanceStore и PersistableIdleAction.Выгрузка

#workflow-foundation #workflow-foundation-4

#рабочий процесс-основа #workflow-foundation-4

Вопрос:

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

Для устранения этой проблемы я использовал ANTS Memory Profiler. Выводится график сохранения объекта, показывающий, что внутренний объект привязан к экземпляру моего workflow.

альтернативный текст
(источник: rohland.co.za)

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

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

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

Есть какие-нибудь подсказки?

Комментарии:

1. Если вы хотите воспроизвести это поведение, откройте следующий пример, предоставленный библиотекой примеров WCF и WF от Microsoft — WFBasicExecutionControllingWorkflowApplicationsCS. Если я открываю приложение и запускаю несколько экземпляров workflow, они завершаются, но память не освобождается.

Ответ №1:

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

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

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

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

Комментарии:

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

2. Это может быть особенностью класса SqlClient, вы могли бы попробовать спросить на форуме social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders /…