Ошибка System.OutOfMemoryException в NDde.dll
Atom Ответить
25.07.2012


Использую 4.1.3, скачанный из репозитория с номером 18403. Программа компилируется и нормально работает около часа. При запуске занимает память около 400Мб, но через час вываливается эта ошибка. Программа уже использует 1.3-1.5Гб (по диспетчеру задач смотрю). Пишет "нет исходных файлов для отладки", значит это в защищенной длл. Скриншоты прикрепляю и проект, на котором ошибка выскакивает, тоже. Стратегия простая на часовых свечках. При работе подписывается на стакан и на свечки (candleManager) по одному инструменту RIU2. Если будете запускать, то она там перед работой качает с финама исторические данные в каталог d:\historyC#_60. Если мешает, то, наверное, этот участок можно закомментировать.

На скриншотах можно увидеть, что ошибка вываливается в NDde.Foundation.Server.DdemlServer.ProcessCallBack().

Возможно, баг, а, возможно, я неправильно понимаю логику S#. Посмотрите, пожалуйста, в чем тут может быть причина?

Проект, на котором через час вываливается ошибка: https://dl.dropbox.com/u...B0%D0%B2%D0%BA%D0%B8.rar
ошибка1.png 47,6KB (1) ошибка2.png 17,3KB (1) ошибка3.png 32,9KB (0) ошибка4.png 36,3KB (2)

Теги:


Спасибо:




9 Ответов
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.07.2012
Ответить


Серёжа Сорокин Перейти

На скриншотах можно увидеть, что ошибка вываливается в NDde.Foundation.Server.DdemlServer.ProcessCallBack().


Когда не хватает памяти, то упасть может где угодно, где выделяется память. Хоть 1 байт. Может проблема в тиках? Фильтр на этой таблице стоит?
Спасибо:

Alexander

Фотография
Дата: 25.07.2012
Ответить


Оптимизируйте приложение по памяти, 1.5 гига - как-то мягко говоря много.
Спасибо:

Серёжа Сорокин

Фотография
Программист
Дата: 25.07.2012
Ответить


Цитата:

Когда не хватает памяти, то упасть может где угодно, где выделяется память. Хоть 1 байт. Может проблема в тиках? Фильтр на этой таблице стоит?

В терминале стоит фильтр "все фьючерсы". Но ведь в коде я только один раз подписываюсь на тики по инструменту RIU2:
Код
_trader.RegisterMarketDepth(sec);

Разве может быть в тиках?

Цитата:
Оптимизируйте приложение по памяти, 1.5 гига - как-то мягко говоря много.

Так у меня там всего 4 индикатора и один candleManager из переменных, которые именно накапливают данные. Это точно не где-то в переменных самой библиотеки копится?

В алгоритме я использую подписку на изменение свечки:
Код
_candleManager.Processing -= (seria, candle) => CandlesChanged(seria, candle);

Это событие срабатывает очень часто - несколько раз в секунду. А внутри него:
Код
private void CandlesChanged(CandleSeries seria, Candle thisCandle)
        {
            foreach (var candle in seria.GetCandles<Candle>().Where(candle => _lastCandle == null || candle.OpenTime >= _lastCandle.OpenTime))
            {
                sar.Process((CandleIndicatorValue)candle);
                adx.Process((CandleIndicatorValue)candle);
                
                
                if (_lastCandle != null && candle.OpenTime > _lastCandle.OpenTime)
                {
                    lastAdx = adx.MovingAverage.LastValue;
                    _lastCandle = candle;
                    this.AddInfoLog("Перешли на следующую свечку со временем открытия {0}.", _lastCandle.OpenTime);

                    sma3.Process((DecimalIndicatorValue)candle.ClosePrice);
                    sma12.Process((DecimalIndicatorValue)candle.ClosePrice);
                }
                if (candle.OpenTime != _timeFrame.GetCandleBounds(Trader.MarketTime, Security.Exchange).Min && !Allloaded)
                    continue;
                if (_candleManager.Container.GetCandles(_candleManager.Series.First()).Count() < 18)
                    continue;
                
                Allloaded = true;
                var order = AlterantiveSignal(candle, _candleManager);
                if (AlterantiveSignal == null || order == null) return;
                var child = new MarketQuotingStrategy(order, Security.MinStepPrice, lastMarketDepth.BestPair.SpreadPrice);
                ChildStrategies.Add(child);
                currentQuoting = child;
                child.Start();
            }
        }

То есть из серии выбирается последняя свечка (условие Where), по ней несколько раз в секунду срабатывает Process у индикаторов. Но я смотрел исходный код индикаторов (adx смотрел). Ведь если время свечки то же, что у прошлой добавленной, то они просто обновляются, они не копят в себе слишком большой буфер? Или все-таки накапливают?
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.07.2012
Ответить


Серёжа Сорокин Перейти

В терминале стоит фильтр "все фьючерсы". Но ведь в коде я только один раз подписываюсь на тики по инструменту RIU2:


Для Квика фильтр не работает. Все что льет Квик, то и приходит.
Спасибо:

Серёжа Сорокин

Фотография
Программист
Дата: 25.07.2012
Ответить


Цитата:
Для Квика фильтр не работает. Все что льет Квик, то и приходит.

И копится? Просто я не создавал специальных переменных, значит это в самой библиотеке? А очистить можно - например, трейдер обнулить?
Автор топика
Спасибо:

Moadip

Фотография
Автор статей Программист
Дата: 25.07.2012
Ответить


Зачем с приходом каждого нового тика делать расчет индикатора? Вроде как логично делать расчет когда свечка полностью сформировалась.

Каждый раз, когда срабатывает событие Processing, беря все свечки по серии
Код

seria.GetCandles<Candle>()

вы таким образом убиваете скорость работы робота.

Последняя свечка и так передается в обработчик - thisCandle.
Спасибо:

Серёжа Сорокин

Фотография
Программист
Дата: 26.07.2012
Ответить


Цитата:
Зачем с приходом каждого нового тика делать расчет индикатора? Вроде как логично делать расчет когда свечка полностью сформировалась.


А я хочу формировать сигналы внутри свечки. За час может многое произойти и хочу оперативно реагировать на это.

Цитата:
Каждый раз, когда срабатывает событие Processing, беря все свечки по серии
Код:


Цитата:
seria.GetCandles<Candle>()



вы таким образом убиваете скорость работы робота.


Я знаю. Просто при первом срабатывании этого события thisCandle уже приходит непервая. Вот чтобы ее не пропустить. Да и разница в производительностью между выборкой всех свечек серии и отбором среди них одной последней (по времени) и просто последней несущественна, если у меня часовки. Их всего 30-40 штук.

Сегодня попробую запустить сначала с обновлением индикаторов раз в час. Потом с более строгим отбором всех сделок в квике. Посмотрим, что получится. Smile
Автор топика
Спасибо:

Серёжа Сорокин

Фотография
Программист
Дата: 27.07.2012
Ответить


Ограничил количество инструментов в таблице всех сделок - только RIU2. Еще урезал проект - оставил только трейдера и CandleManager, который строит часовые свечки по RIU2.
Последний запуск программы в
15:14, в диспетчере она занимала 234600 Кб, при этом в _trader.Trades было довольно много сделок - 337 899 штук.
Но размер продолжает расти! В
15:27, памяти 705 068 Кб, сделок 344 658.

То есть не из-за количества сделок растет размер. И еще раз говорю - моих переменных, кроме CandleManager, никаких нету, накапливающих данные.

После этого прямо на глазах потребляемая память растет примерно на 9МБ в секунду. И еще через три минуты становится около 1.3Гб, расти перестает на минуту. Потом вываливается ошибка, описанная в первом посте.

У проекта удалил вообще все, кроме трейдера и кендл менеджера. Вот проект: https://dl.dropbox.com/u...%BA%D0%B8_2012_07_27.rar

Я практически уверен, что где-то утечка памяти. Подскажите, пожалуйста, как вычислить эту ошибку?
Автор топика
Спасибо:

Alexander

Фотография
Дата: 27.07.2012
Ответить


Регулярно использую candleManager, никогда проблем с утечками не было.
У вас значит что-то в коде не то.

Поставьте профайлер памяти да посмотрите где память утекает от вас. К примеру профайлер от JetBrains.
Спасибо:


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy