#workflow-foundation #workflow-foundation-4
#рабочий процесс-основа #workflow-foundation-4
Вопрос:
Эта конкретная проблема сводит меня с ума. Интересно, сталкивался ли кто-нибудь с подобной проблемой. Если я загружаю рабочий процесс, затем выгружаю его и выполняю моментальный снимок памяти, то результат предсказуем — моего рабочего процесса больше нет в памяти. Однако, если я загружу рабочий процесс и установлю для действия PersistableIdle значение PersistableIdleAction.Выгрузите и дайте рабочему процессу простаивать рабочий процесс остается в памяти, даже если выполняется действие выгрузки.
Для устранения этой проблемы я использовал ANTS Memory Profiler. Выводится график сохранения объекта, показывающий, что внутренний объект привязан к экземпляру моего workflow.
(источник: rohland.co.za)
Кто-нибудь еще может проверить эту проблему? Мой код сводится к следующему:
- Создайте SqlWorkflowInstanceStore и настройте дескриптор владельца блокировки
— На этом этапе я делаю снимок памяти - Создайте экземпляр Workflow1
- Установите действие PersistableIdle
- Примените хранилище экземпляров к Workflow1
- Настройте обработчики событий действия для Idle, выгрузки, необработанного исключения и т.д.
- Сохранение экземпляра workflow
- Запустите экземпляр workflow
- Дождитесь, например, бездействия (вызвано действием задержки)
- Убедитесь, что действие выгрузки запущено
— На этом этапе я делаю второй снимок памяти
Из приведенного выше изображения ясно, что единственным объектом, ссылающимся на 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 /…