none
Требуется найти утечкку использования ОЗУ RRS feed

  • Вопрос

  • Рост использования ОЗУ происходит вв программе по работе с online биржевыми данными т е рост происходит через 5 часов работы программы.

    Нужно в момент времени посмотреть под что идет ОЗУ. Сделал профилирование, но файл в 3 Гб не открывается.

    Программа Visual Studio 2010.

    Есть еще момент, как посмотреть что какая-то коллекция создается много раз т е оценить количество экземпляров коллекции с определенным именем. 

    21 ноября 2012 г. 15:47

Ответы

  • private void dgProfileDiv_RowDetailsVisibilityChanged(object sender, System.Windows.Controls.DataGridRowDetailsEventArgs e)
            {
                var c = e.Row;
            }
    
            private void dgProfileDiv_LoadingRow(object sender, System.Windows.Controls.DataGridRowEventArgs e)
            {
                ProfilDiv item = e.Row.Item as ProfilDiv;
                if (item != null)
                {
                    decimal rowPrice = item.PriceOB;
                    if (rowPrice == Model.CurrentPriceModel)
                    {
                        e.Row.Background = new SolidColorBrush(Color.FromArgb(100, 198, 187, 137));
    
                    }
                    else e.Row.Background = new SolidColorBrush(Color.FromArgb(100, 32, 29, 74));
    
    
    
                }

    Ну и ковертеры цвета использую в пределах 10 штук, но массивы данных Observable, связанные с DataGrid имеют ограничения на рост и сыше 100 удаляются. В некоторых таблицах фиксированное количество строк и в них иеняются значения и подсветка через конверетры, по идее свойства ячеек через конвертеры наслаиваться не должны.

    Поэтому и напрягает рост с 150 Мб до 1 Гб к концу дня при том, что в отладчике все коллекции обрубленные и не лолжны вести к увеличению ОЗУ. 


    22 ноября 2012 г. 8:18

Все ответы

  • Проверьте, вы нигде не подписываетесь на события? Если да, то не забывайте отписываться, а то это ссылки, а следовательно сборщик мусора собрать их не может...

    22 ноября 2012 г. 7:45
    Отвечающий
  • private void dgProfileDiv_RowDetailsVisibilityChanged(object sender, System.Windows.Controls.DataGridRowDetailsEventArgs e)
            {
                var c = e.Row;
            }
    
            private void dgProfileDiv_LoadingRow(object sender, System.Windows.Controls.DataGridRowEventArgs e)
            {
                ProfilDiv item = e.Row.Item as ProfilDiv;
                if (item != null)
                {
                    decimal rowPrice = item.PriceOB;
                    if (rowPrice == Model.CurrentPriceModel)
                    {
                        e.Row.Background = new SolidColorBrush(Color.FromArgb(100, 198, 187, 137));
    
                    }
                    else e.Row.Background = new SolidColorBrush(Color.FromArgb(100, 32, 29, 74));
    
    
    
                }

    Ну и ковертеры цвета использую в пределах 10 штук, но массивы данных Observable, связанные с DataGrid имеют ограничения на рост и сыше 100 удаляются. В некоторых таблицах фиксированное количество строк и в них иеняются значения и подсветка через конверетры, по идее свойства ячеек через конвертеры наслаиваться не должны.

    Поэтому и напрягает рост с 150 Мб до 1 Гб к концу дня при том, что в отладчике все коллекции обрубленные и не лолжны вести к увеличению ОЗУ. 


    22 ноября 2012 г. 8:18
  •   if (!flgRun)
                {
                   (NameSymbol);
                                    ManagerBrokerData.Instance.evntDomChange += new EventDomChanged(Instrument_EventDOMChanged);
                    ManagerBrokerData.Instance.evntNewData += new EventTickData(Instrument_EventTickData);
                    btnRun.Content = "Stop";
                    //Instrument.EventDOMChanged += new EventDomChanged(Instrument_EventDOMChanged);
                }
                else
                {
                    ManagerBrokerData.Instance.evntDomChange -= Instrument_EventDOMChanged;
                    ManagerBrokerData.Instance.evntNewData -= new EventTickData(Instrument_EventTickData);
                    btnRun.Content = "Run";
                }

    ManagerBrokerData.Instance.evntNewData -= new EventTickData(Instrument_EventTickData);

    Здесь ошибку сделал, она может привести к росту памяти?

    22 ноября 2012 г. 8:46
  • Да. Как я уже сказал выше, если вы подписываетесь на событие, и не отписываетсь, то объект из памяти никогда не удалится, т.к. на него есть ссылка и сборщик мусора его игнорит.
    22 ноября 2012 г. 8:50
    Отвечающий
  • Это исправил. Но рост использования оперативной памяти не прекратился. Надо все-таки профилировщик как-то заставить показать в момент времени использование ОЗУ программой.

    По поводу событий. Вот подписался я на событие и полученные данные обсчитал и нужные результаты записал себе в коллекции. Больше устаревшие данные в памяти по событиям мне не нужны, как их затирать в памяти?

     Все таки события бывает не один десяток раз в секунду поступают.


    22 ноября 2012 г. 13:15
  • Привет.

    Если ссылок на те данные, что поступают в событие больше нигде не будет и они не будут храниться где-нибудь глобально в программе - то GC должен собрать их. Это в том случае если все объекты у вас управляемые. Для неуправляемых объектов нужно вызывать Dispose или использовать конструкцию using.

    По профилированию, попробуйте посмотреть возможности встроенного профайлера - меню Analyze - Performance Wizard и выберите опцию профилирования памяти.

    Также можно посмотреть сторонние профайлеры, например - ANTS Memory Profiler 7.4, .NET Memory Profiling или воспользоваться WinDbg, как говорится в ответе здесь


    Для связи [mail]

    30 ноября 2012 г. 8:13
  • Профилировщик показывает, что 70-80% ОЗУ,как и по производительности происходит в App.Main(), у меня используется модель View-ViewModel, все расчеты там происходят, в MainWindow только основное окно.

    Активно использую WPF DataGrid, их несколько штук, активно пересчитываются данные в них, все они привязаны к ObservableCollection и их я чищу  постоянно:

     if (Method_CDom1.Count > 5000)
                        {
                            Method_CDom1.RemoveAt(5000);
                                                }

    Есть обработчики событий

     ManagerBrokerData.Instance.evntDomChange += new EventDomChanged(Instrument_EventDOMChanged);

    в секунду может быть десятки раз, с утра до вечера работает. Данные идут в  VieModel через вызов функции этого модуля в View.xaml..cs

      void Instrument_EventDOMChanged(object sender, List<DomData> DomAsks, List<DomData> DomBids, DateTime DateTimeChanged)        {
                
                
                if (Instrument.Symbol != this.cmbTicker.Text)
                    return;
    
                if (Model != null)
                {
    
                    Model.DOMChanges(Instrument, newTick);
                    
    
                }
              ();
            }

    В принципе все данные передаются в эту функцию и не возвращаются.

    Еще использую метод Clear() для ObservableCollection.


    1 декабря 2012 г. 10:10