Общие вопросы по разработке > Тонны памяти в оптимизации. Вызвать GC вручную?..

Общие вопросы по разработке в Альфа-Директ 4. Обсуждение разработки пользовательских индикаторов, стратегий.
BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 08 янв 2021, 11:59

Привет всем.

Оптимизирую свое творчество, столкнулся с проблемой.

При оптимизации выделенная память начинает бурно расти, превышает объем физической памяти, после чего комп, естественно, морозится, и приходится прекращать оптимизацию (либо даже просто убивать АД). После прекращения оптимизации память освобождается очень медленно, время исчисляется минутами (~5 минут и более)!

Пробовал в 3-х вариантах.

Код: Выделить всё

function Initialize()
{
...
 AddGlobalVariable("Cnt", Types.Int, 0);
}

function OnUpdate()
{
 if((int)Cnt==0)
 {
  if(...)  // проверка соотношения параметров скрипта
   Stop();  // вариант 1 - самый быстрый
// return;  // вариант 2 - помедленнее, т.к. проходится по всему заказанному периоду тестирования, но ничего не делает
// вариант 3 - позволить работу с неверным соотношением, самый медленный; делает всё, что прописано в скрипте
  Cnt++;
 }
 ...
}


Проверка соотношения параметров скрипта делается для того, чтобы пропускать бессмысленные сочетания параметров, которые перещелкивает тестировщик (вроде SMAfast>=SMAslow).

Самый плохой вариант - первый (память загаживается почти мгновенно), затем второй (помедленнее), затем третий (но все равно не спасает).

Из сделанных наблюдений прихожу к выводу, что проблема м.б. в сборщике мусора. Похоже, что он работает слишком лениво и не успевает очищать память после отработки очередной "точки" тестирования.

Вопрос: реально ли из скрипта прочесть размер занимаемой памяти и вручную вызвать GC, если он становится слишком велик?
Если да, то большая просьба показать, как это сделать.

TIA.

BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 08 янв 2021, 12:32

Код: Выделить всё

 if((int)Cnt==0)
 {
  Cnt++;
  GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true); // блокирующий вызов сборщика
  if((int)SMAfast>=(int)SMAslow)
  {
   Stop();
  }
 }


Вроде получше на глаз, но все равно не спасает...
Т.е. либо реально все же не вызывается, либо не в сборщике дело...

Возможно, что после прохождения "точки" теста (с текущим набором параметров) тестировщик не освобождает рабочий экземпляр класса процессора данных, а оставляет его (вместе с какими-то большими вычисленными рядами) до конца тестирования, чтобы потом извлечь из него результаты...

BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 08 янв 2021, 13:09

Хмм...
Проблема в чем-то другом.
Есть у меня самодельный индикатор (вроде вполне невинный), после добавления которого на график (т.е. просто без всякого тестирования/оптимизации) начинает расти используемая память.
Буду копать...

Upd: индикатор ни при чем, объем памяти просто (существенно и медленно) колеблется, но не растет.

Upd:
В стратегии был вызов "сложного" индикатора (в котором, в свою очередь, вызовы индикаторов от индикаторов и рисование результатов, конечно). Ничего криминального, но всё плохо, как рассказано раньше.

Перенес код из индикатора в стратегию (те же вызовы индикаторов), но уже без рисования.
Пока вроде всё нормально...

Странно как-то в общем, причины проблемы не видно.

ensh
Сообщения: 218
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 39 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение ensh » 08 янв 2021, 23:15

Рисование в терминале сделано криво, без освобождения контекста графических объектов, поэтому при всяких интенсивных отрисовках память улетает и сборщик не поможет

BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 09 янв 2021, 08:36

Надо будет посмотреть в диспетчере задач на объекты GDI (и прочие ресурсы). Хотя сейчас редко кто рисует "ручками" на низком уровне, а более высокоуровневые библиотеки вряд ли не делают нужные действия, это уж было бы совсем не комильфо ...

BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 09 янв 2021, 14:44

На глаз утечек системных ресурсов (объекты USER/GDI, дескрипторы) в процессе оптимизации не видно. Число их несколько увеличивается до некоторого предела, затем остается постоянным (ну или почти постоянным, по крайней мере, лавины какой-то не наблюдается).

Не подскажете, как отлаживать и код своего скрипта (индикатора и/или робота), и процесс оптимизации?
Я нашел какой-то инструмент dnSpy, с виду приличный вполне, запустил из-под него. Да, есть дебаг пошаговый, но нужна наводка, где ставить точки прерывания. Например, поставил наугад в начале

// MTS.BatchOptimization.MTSBatchOptimizer
public void ProcessInstrument(OptimizationTemplate template)

но на нее не выходит. Ну и свои сгенерированные сборки (*.alfa и *.adl) грузятся, очевидно, как-то динамически, надо найти, где они и в какой момент доступны.

Также хотелось бы как-то видеть, как сборки подгружаются/выгружаются, если таковой процесс имеет место. (Есть подозрение, что пользовательские скрипты, в отличие от встроенных (?), сильно замедляют процесс тестирования. А вдруг это происходит, если скрипт постоянно загружается/выгружается?)

ensh
Сообщения: 218
Зарегистрирован: 28 июн 2017, 13:56
Благодарил (а): 4 раза
Поблагодарили: 39 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение ensh » 09 янв 2021, 23:17

Все пользовательские скрипты индикаторы и роботы компилируются стандартные .net сборки лежат в папочке Bin с расширением tmp.
Сборка грузится в момент исполнения программы в .net один раз и навсегда, пока не закроешь программу или не сделаешь очень грязный финт, но AD на такое не способен.
Так что проблем со сборками нет.
Можно код пользовательских сборок, да и сам AD смотреть опенсорсным (GitHub) проектом ILSpy.
Помню, что индикаторы сделаны не очень, и там возникает ситуация , когда индикатор начинает повторно считаться с самого начала в каждой точке, что как бы при большой количестве расчетных точек - черевато...

BugsDigger
Сообщения: 533
Зарегистрирован: 11 ноя 2018, 17:11
Благодарил (а): 21 раз
Поблагодарили: 91 раз

Re: Тонны памяти в оптимизации. Вызвать GC вручную?..

Непрочитанное сообщение BugsDigger » 10 янв 2021, 07:11

Упомянутый dnSpy (тоже открытый с гитхаба) позволяет не только дизать код, но и отлаживать! Мало того, вчера мне это даже удалось сделать, только не совсем понял - как. :) Вначале он жаловался, что брекпойнт недостижим, а потом я что-то "ткнул" научно - и на нем отладчик остановился, и можно делать шаги, смотреть переменные (почему-то не все), т.е. работает. Попробую сегодня воспроизвести позитивный опыт в "сознательном" режиме.

ОК, спасибо за информацию о загрузке сборок; по крайней мере о ней как о причине медлительности можно не беспокоиться.
Да, снижение производительности вполне мыслимо из-за повторных пересчетов (из-за чего ж еще тогда).

Еще один вопрос, вдруг знаете.
В CustomDraw - сериях методы рисования добавляют к бару дополнительную информацию о способе его отображения. Как вы думаете, имеет ли смысл пропускать вызов рисования при вычислениях (просто сделать параметр и по нему пропускать операторы рисования в скрипте), если рисование не нужно? Вроде как и памяти поменьше, и лишний кусок кода пропустится. Или это "стрельба по воробьям" и мало что даст?


Вернуться в «Общие вопросы по разработке»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 21 гость