Гоняю 1000 итераций, где в каждой создаю EmulationTrader и все необходимое, он отрабатывает, уничтожаю объекты. Память накапливается, и программа заканчивается с OutOfMemory Exception. Вызываю для всех объектов где надо Dispose(), где надо null, отписываюсь от событий, но память все равно течет.
Профайлером ANTS Memory Profiler я увидел, что продолжают висеть в памяти EmulationTrader-ы и LocalMarketDateDrive-ы. На них ссылаются делегаты (видимо, их же обработчики, подписавшиеся на события извне). Вот последовательность взаимных ссылок, которые держат объекты (читать лучше снизу вверх: удерживаемый объект - внизу, корневая удерживающая ссылка - вверху):
- Делегат LocalMarketDataDrive-а
static LazyHelpers _delegates (references to ->)
Ecng.Collections.SyncrhonizedDictionary<Object, Delegate> _inner ->
Dictionary<Object, Delegate> entries ->
it's [0].Value ->
(delegate) System.Func<CachedSyncronizedOrderDictionary<DateTime, DateTime>> (inside LocalMarketDataDrive) ->
LocalMarketDataDrive
- Делегат EmulationTrader-а
static List<Ecng.ComponentModel.EventsContainer> _containers ->
it's _items[0] ->
EventsContainer<Security> _processDataError ->
(delegate) System.Action<Exception> (inside EmulationTrader) ->
EmulationTrader (internal field #=q.....GZQ==)->
LocalMarketDataDrive
Поскольку у меня нет исходников S#, то догадки свои проверить не могу. Могу прислать дампы программы для анализа. Ну, и привести кусочки кода создания/освобождения объектов. Буду очень благодарен за исправления!
UPD. Версия последняя, 4.1.19.1
コメント (12)
ログイン または アカウントを作成, コメントを残すにはログインまたは新規登録してください
static LazyHelpers _delegates (references to ->) Ecng.Collections.SyncrhonizedDictionary<Object, Delegate> _inner -> Dictionary<Object, Delegate> entries -> it's [0].Value -> (delegate) System.Func<CachedSyncronizedOrderDictionary<DateTime, DateTime>> (inside LocalMarketDataDrive) -> LocalMarketDataDrive
Добрый день, pafnuty! Я тоже в одно время интересовался утечками памяти. Обещали исправить, но пока видимо не успешно. Позвольте поинтересоваться с какой целью вы проводите так много итераций? Если вы пишите оптимизитор для тестирования стратегий, то было бы здорово, если вы поделитесь своими мыслями по этому поводу. Просто мы сейчас тоже работаем над этим.
Спасибо за фидбэк. А возможно ли сделать некий мини код (желательно с теми маркет-данными, что идут в нашем дистрибутиве), который бы демонстрировал утечку на итерациях?
Сейчас мы переделываем эмулятор на новый подход, и было бы очень кстати до нового релиза получить такой код. Возможно, мы могли бы его добавить как юнит тест для предотвращения в будущем таких ситуаций.
1. Вот тестовый проект: http://yadi.sk/d/omfHs1P0BFfZq
Не очень мини получилось - я просто выцепил кусок своей программы, выкинул все ненужное. Стратегию взял из SampleHistoryTesting, но переделал ее на свой лад, как я работал с тиками (чтобы можно было увидеть мои утечки, а заодно и средства борьбы с ними). Я думаю, что можно также прозрачно подставить туда и исходную SmaStrategy, только переопределить в ней Clone() и добавить конструктор по умолчанию. Ну, и CandleManager подцепить, сейчас я работал без него.
Сразу отмечу, что пока я не гонял этот код на свои собственные утечки. За основу брал свою последнюю версию, а что получилось после изменений, не проверил.
Немного кода там осталось висеть в комментариях - я оставил свои соображения по поводу утечек, как есть. Некоторые куски кода демонстрируют возможные, на мой взгляд, сценарии использовния. В общем, если появятся какие-то вопросы, я готов ответить.
2. Попутно я боролся с утечками. После тех брутальных Clear() я смог еще кое-что обнаружить и убить (наверное, неаккуратно). Удалось сбросить до ~60Мб на 1000 итераций.
Mikhail Sukhov
Утечка оказалась существенной - на каждой итерации ~ +1Мб. Незначительные лики в StockSharp зацепились здесь (возможно, что и не лики вовсе - буду еще гонять):
(Еще какие-то String-и висят и массивы... но это уже что-то мое, а не StockSharp.)
Bond Да, делаю оптимизатор. Мысли у меня такие: у стратегии есть набор параметров, от которых она зависит. Оптимизатор перебирает их в заданном диапазоне (включая диапазон дат), для каждой уникальной комбинации параметров запускает тест (по схеме, предложенной здесь: Тестирование на истории (оптимизация)). Набор параметров и результаты теста (все данные из StatisticManager, а также накопленную историю Orders, PnLs, Positions) он накапливает в базу данных. Для распределенного тестирования на нескольких машинах планирую использовать либо удаленный сервер БД, либо репликацию между локальными серверами (если медленное соединение, либо сервер не всегда доступен).
Доброго времени суток! Мы тоже сейчас пытаемся определиться с архитектурой оптимизатора. С количеством оптимизируемых параметров:
Да, спасибо, уже примерно понятно из-за чего.
Оффтоп: Bond А давайте вынесем наш с вами разговор в отдельный топик, чтобы не засорять главную тему. Отношения к утечкам памяти он не имеет. В будущем будем стараться делать это сразу. Я вот что-то не уследил. :)
Обнаружил тут, что в своем исходнике я 2 раза подписывался/отписывался на стаканы для одного и того же Security (в обоих случаях один и тот же объект - клон):
Возможно, это тоже приводит к утечке (хотя, я так не думаю).