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

Утечки памяти при тестировании на исторических данных
Atom
4/2/2012


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

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

Code
		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)




Thanks:


< 1 2 3 
Den

Avatar
Date: 2/1/2013
Reply


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


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

Mikhail Sukhov

Avatar
Date: 2/1/2013
Reply


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


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


Я про кодеплекс.
Thanks:

ak

Avatar
Date: 2/3/2013
Reply


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

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

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



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



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

FiNick

Avatar
Date: 2/7/2013
Reply


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

ak

Avatar
Date: 2/7/2013
Reply


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

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

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

Code
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 для запущенного приложения - сразу станет понятно, где течет.
Thanks:
< 1 2 3 

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy