PenCollector: not enough space in array

 

Попытка сделать тестовый рисунок на графике приводит к появлению сабжа в журнале.

При этом рисующий скрипт отрабатывает без каких-либо ошибок или сообщений в логах экспертов.

Картинка, которую пытался нарисовать скрипт такая

На самом деле на картинке должно было быть три полосы, которые показывают чистые цвета: синий от С'0,0,0' до С'0,0,255', зеленый от С'0,0,0' до С'0,255,0' и красный от С'0,0,0' до С'255,0,0'. Пардон, если перепутал места синего и красного - в справочнике слишком невразумительно это сказано и примеры не дают возможности разобраться. Полосы рисуются вертикальными отрезками, так что для создания каждой полосы используется 256 объектов. То есть всего 768 отрезков, что совсем немного, я бывало рисовал их десятками тысяч и все было нормально.

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

Кроме того, сообщение в сабже, которое, естественно, тоже с этим связано. Скрипт отрабатывает и завершается без ошибок, а сообщение продолжает генериться. При этом нет ссылки на код ошибки и, в результате, непонятно где искать. Тем более, что при отрисовке никакие массивы не используются.

Ниже привожу код процедуры, которая делает этот рисунок:

//+------------------------------------------------------------------+
void ColourTestHor(double ZRLin,datetime CTDat,int ncl,int sbl,int sgr,int srd)
{ double sp,ep,xunit,yunit;
int nn,num,CPrd,nrd,ngr,nbl,clr,ww=0;
string let,name,zero,clnam;
datetime st,et;

if (srd<0) srd=0; else if (srd>255) srd=255;
if (sgr<0) sgr=0; else if (sgr>255) sgr=255;
if (sbl<0) sbl=0; else if (sbl>255) sbl=255;


if (ncl==1) clnam="red"; else
if (ncl==2) clnam="grn"; else
if (ncl==3) clnam="blu";


CPrd=Time[0]-Time[1];
for (nn=0; nn<=255; nn++)
{ zero="000"+DoubleToStr(nn,0);
num = StringLen(zero);
name=clnam + StringSubstr(zero,num-3,3);
st=CTDat+nn*CPrd; et=st;
sp=ZRLin; ep=sp+Point*25;


if (ncl==1) clr=nn+sgr*256+sbl*256*256; else
if (ncl==2) clr=srd+nn*256+sbl*256*256; else
if (ncl==3) clr=srd+sgr*256+nn*256*256;


if (ObjectFind(name)<0) ObjectCreate(name,OBJ_TREND,ww,0,0,0,0);
ObjectSet(name,OBJPROP_TIME1,st);
ObjectSet(name,OBJPROP_PRICE1,sp);
ObjectSet(name,OBJPROP_TIME2,et);
ObjectSet(name,OBJPROP_PRICE2,ep);
ObjectSet(name,OBJPROP_COLOR,clr);
ObjectSet(name,OBJPROP_STYLE,STYLE_SOLID);
ObjectSet(name,OBJPROP_WIDTH,1);
ObjectSet(name,OBJPROP_RAY,false);
}

return;
}
//+------------------------------------------------------------------+

 

Вы банально переполнили кеш стилей графических объектов. Не самый лучший вариант создавать такое количество графических профайлов.


Так как нам приходится постоянно выводить большое количество графических объектов в разных вариантах, мы используем кеш стилей ранее созданных объектов ради ускорения вывода. В Вашем случае кеш успевает переполниться на инициализации не достигая процедуры автоочистки.


Просто уменьшите количество вариантов раскраски (градиент с шагом 1 явно лишний) и это реально ускорит работу терминала. Вы ведь создаете огромное количество уникальных объектов с уникальными стилями отрисовки. А это очень дорого по ресурсам.

 

Спасибо, понял.

Как я уже писал, это был только тест, чтобы прояснить себе некоторые вопросы по работе с цветами.

Дело в том, что мне, в порядке проводимого исследования, необходимо разобраться с видом поверхности, представляющей функцию двух переменных. Цветом я хотел, как это обычно делается, отобразить значение функции над двумерной прямоугольной областью значений ее двух аргументов. Поскольку про кеш стилей нигде ничего не сказано, то это и выяснилось таким неожиданным образом.

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

Поскольку это только исследование и работать в режиме реального времени не будет никогда, то вопросы быстродействия здесь меня совершенно не волнуют.

Поэтому, если Вам не трудно, растолкуйте, посоветуйте, укажите верный путь ... :-)

 

Ренат, Слава отзовитесь.

Дайте pls необходимую информацию по кешу стилей. Должен же пользователь знать о границах допустимых действий и о своих возможностях при работе.

Или это секрет ?

 

Нарвался на такую же проблему. И тоже при рисовании градиента.

Заметил, что переполнение происходит примерно после 500-го стиля. Лечится только перезапуском терминала.

Для обычной работы, конечно, этого более чем достаточно, но для "художников" можно было бы сделать и больше.

Или просто исправить ошибку переполнения - принудительно очищать буффер. А то я ее заметил когда было напечатано 150 Мб логов - зачем такое поведение?

 
Renat >>:

Вы банально переполнили кеш стилей графических объектов. Не самый лучший вариант создавать такое количество графических профайлов.


Так как нам приходится постоянно выводить большое количество графических объектов в разных вариантах, мы используем кеш стилей ранее созданных объектов ради ускорения вывода. В Вашем случае кеш успевает переполниться на инициализации не достигая процедуры автоочистки.


Просто уменьшите количество вариантов раскраски (градиент с шагом 1 явно лишний) и это реально ускорит работу терминала. Вы ведь создаете огромное количество уникальных объектов с уникальными стилями отрисовки. А это очень дорого по ресурсам.

А можно ли както принудительно вызывать процедуру автоочистки или ручной очистки? Ведь нашли же "внутренний тик" в "MetaTrader4_Internal_Message".

А мне действительно нужно нарисовать более 3 тыс (да-да - именно столько!) текстовых объектов с очень разными цветами. Терминал их спокойно отрисовывает но сообщение в логе раздувает лог до сотни мегабайт...

 

Тоже такое же было.

В моём случае видимость объектов регулировал с помощью видимости на ТФ. Стал удалять ненужные объекты с других ТФ и проблема исчезла.

 
В моем случае это не сработает ибо проблема видимо не в видимости объектов а в их количестве - на каждом тике мне приходится их все прибивать и по новой перерисовывать.
 
Сегодня посмотрим что можно сделать - попробуем активно чистить кеш. Скорость работы правда может упасть.
 

Переделали работу кеша. Вот что было и что стало при выводе градиентов:





Апдейт будет завтра или послезавтра.

 
komposter писал(а) >>

Нарвался на такую же проблему. И тоже при рисовании градиента.

Заметил, что переполнение происходит примерно после 500-го стиля. Лечится только перезапуском терминала.

Для обычной работы, конечно, этого более чем достаточно, но для "художников" можно было бы сделать и больше.

Или просто исправить ошибку переполнения - принудительно очищать буффер. А то я ее заметил когда было напечатано 150 Мб логов - зачем такое поведение?

Экспериментальным путем (самый лучший способ - потыкать пальцем :-) определил, что размер кэша стилей = 512. Переделал свой скрипт так, чтобы укладываться. Проблема разрешилась.

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

Жаль только что ответа пришлось ждать 3.5 месяца. Сакраментальную цифирь 512 можно было бы огласить и пораньше. Из вежливости.

Причина обращения: