Утечки памяти при тестировании на исторических данных


Утечки памяти при тестировании на исторических данных
Atom
02.04.2012


Обнаружил утечки памяти при тестировании на исторических данных, при многократном повторении.
Сначал грешил на свою стратегию, потом попробовал запускать пример SampleHistoryTesting многократно,
При достижении 30-40 повторений программа подвисала, не выдавая никаких сообщений.

Далее, для чистоты эксперимента подправил код SampleHistoryTesting:

Код
		private void StartBtn_Click( object sender, RoutedEventArgs e ) {
				
			for( int i = 1; i < 1000; i++ ) {
				Run();

				if( _trader.State != EmulationStates.Started ) { Thread.Sleep( 10 );  }
				if( _trader.State != EmulationStates.Stopped ) { Thread.Sleep( 10 ); }
			}

			MessageBox.Show( "Закончено" );
		}
		
		
		private void Run()
		{
		
		// Ну а тут сам код стратегии, что был раньше в StartBtn_Click 
		
		...
		
		// изменил только период, для более быстрого тестирования
			var startTime = new DateTime(2009, 6, 1);
			var stopTime = new DateTime(2009, 6, 3);
		
		....
		
		}



После запуска данный код через некоторое время выдает Out of memory эксепшн.
(Пробовал, как с включенным выводом инфы в форму, так и выключеным)

на 100 итерациях уже все нормально проходит.

Памяти достаточно - 4 гб озу


Текст исключения:

System.OutOfMemoryException: Выдано исключение типа "System.OutOfMemoryException".

в System.Linq.Buffer`1.ToArray()
в System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
в Ecng.Common.RandomArray`1..ctor(T min, T max, Int32 count)
в StockSharp.Algo.Testing.MarketDataGenerator`1.Init()
в StockSharp.Algo.Testing.TrendMarketDepthGenerator.Init()
в StockSharp.Algo.Testing.EmulationTrader.Start(DateTime startDate, DateTime stopDate)
в SampleHistoryTesting.MainWindow.Run() в C:\Projects\VS\OrigSampleHistoryTesting\MainWindow.xaml.cs:строка 219
в SampleHistoryTesting.MainWindow.StartBtn_Click(Object sender, RoutedEventArgs e) в C:\Projects\VS\OrigSampleHistoryTesting\MainWindow.xaml.cs:строка 63
в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
в System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
в System.Windows.Controls.Primitives.ButtonBase.OnClick()
в System.Windows.Controls.Button.OnClick()
в System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
в System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
в System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
в System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
в System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
в System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
в System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
в System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
в System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
в System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
в System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
в System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
в System.Windows.Input.InputManager.ProcessStagingArea()
в System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
в System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
в System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
в System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)




Спасибо:


< 1 2 3 
Den

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


Mikhail Sukhov Перейти
На последней версии воспроизводиться?


ak выше писал "А между тем, проблема с EmulationTrader осталась и в последней версии S# (4.1.7.0). "
Спасибо:

Mikhail Sukhov

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


Den Перейти
Mikhail Sukhov Перейти
На последней версии воспроизводиться?


ak выше писал "А между тем, проблема с EmulationTrader осталась и в последней версии S# (4.1.7.0). "


Я про кодеплекс.
Спасибо:

ak

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


Потестил на последней сборке #22766 - но моих тестах ситуация изменилась кардинально.

Тестировал на 48 EmulationTrader'ах и 3 торговых днях.

Предыдущая версия (не уверен, что 4.1.7.0, возможно я обновлялся из trunk'а):
Пиковое потребление: 1200+ МБ
Потребление после завершения теста и удаления EmulationTrader'ов: ~600 МБ



Новая версия: #22766
Пиковое потребление: ~500 МБ
Потребление после завершения теста и удаления EmulationTrader'ов: ~140 МБ



Спасибо. Позже я еще внимательно посмотрю на CandleManagerContainer, может и он подтекает )
Спасибо:

FiNick

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


Мне не помогло. Взял с кодеплекса последний changeset 22848, референсы с транка, версия 4.1.8.
Один прогон теста на данных ордерлога за месяц занимают 2Гб, затем делаю Dispose всему чему могу, экземпляру трейдера в том числе, делаю GC.Collect() на всякий случай, память занимаемая приложением не уменьшается. Затем запускается новый прогон теста на том же месяце, память уходит за 7Гб, комп помирает
Спасибо:

ak

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


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

  1. security
  2. storage
  3. portfolio
  4. marketDepthGenerator
  5. candleManager
  6. candleSeries
  7. strategy

Я еще делаю это, записав результат прогона:

Код
trader.StateChanged += (oldState, newState) =>
                {
                    if (trader.State == EmulationStates.Stopped)
                    {
                        trader.UnRegisterMarketDepth(marketDepthGenerator);
                        marketDepthGenerator = null;
                    }
                };

....

trader.StateChanged += (oldState, newState) =>
            {
                if (trader.State == EmulationStates.Stopped)
                {
                    strategy.Stop();
                    candleManager = null;
                    storage = null;
                }        
            };

....

strategy.Trader.Dispose();
strategy.Trader = null;
strategy.Dispose();


Особенно обратите внимание на marketDepthGenerator = null; - из объекта трейдера его не достать никак, поэтому я прицепил этот обработчик в scope'е где у меня есть доступ к только что созданному локальному объекту marketDepthGenerator.

Воспользуйтесь CLR Profiler (http://www.microsoft.com/en-us/download/details.aspx?id=16273), он позволяет очень наглядно посмотреть Managed Heap для запущенного приложения - сразу станет понятно, где течет.
Спасибо:
< 1 2 3 

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

loading
clippy