Ошибки, баги, вопросы - страница 1593

 
на смарт сообщение о отзыве на продукт приходит, в ЛК и сверху на сайте мкл нет.
 


Волшебный скрипт разворачивает время вспять ;-)

 

Волшебный скрипт разворачивает время вспять ;-) 

 
Vladimir Pastushak:
на смарт сообщение о отзыве на продукт приходит, в ЛК и сверху на сайте мкл нет.
так было всегда, помню даже где то просили сделать и на сайт - ибо странно когда тебе оставляют отзывы, а еще если там и вопросы сразу задают, а ты обнаруживаешь только через 2 месяца. :-) 
 

Не баг, но не могу не поделиться 

Пишу

if((!IsRunOnTester() && TimeCurrent() >= D'2016.06.31 23:59'))// для тестировщиков, ограничение работы по времени

 Компилятор выдает варнинг 

invalid date *****.mq4  115 46

Он еще и строковые даты проверяет на правильность даты, я потрясен ) (в июне 30 дней)

 

Видимо это никого это не волнует, но все же напишу еще раз.

Реальная задача: создать массивы общим размером примерно под 100% от свободной памяти, быстро заполнить их числами, произвести расчеты и освободить их.

Пробую получить размер свободной памяти через

int mem_free_mb=(int)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE);

результат : 23987 MB, а физической памяти у меня 12141 MB т.е. в два раза меньше.

Понимаю, что эта цифра для марсиан, но все же верю и пишу скрипт для её тестирования:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
#define PARTS 5

   srand(GetTickCount());
//---
   int mem_free_mb=(int)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE);
   //mem_free_mb=5300;//<--- Столько показывает 'Доступной' в диспетчере задач.
   long mem_for_calc=(long)((double)mem_free_mb*1024*1024);
   long mem_one_part=(long)floor((double)mem_for_calc/PARTS);
   if(mem_one_part>=INT_MAX-1)
      mem_one_part=INT_MAX-1;
//---
   printf("Memory for calc: %0.f MB, parts: %d, part: %0.f MB",mem_for_calc/1024/1024,PARTS,mem_one_part/1024/1024);
   char array1[];
   char array2[];
   char array3[];
   char array4[];
   char array5[];

   int res=ArrayResize(array1,(int)mem_one_part);
   Print("Array1 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",1.0*mem_one_part/1024/1024);

   res=ArrayResize(array2,(int)mem_one_part);
   Print("Array2 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",2.0*mem_one_part/1024/1024);

   res=ArrayResize(array3,(int)mem_one_part);
   Print("Array3 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",3.0*mem_one_part/1024/1024);

   res=ArrayResize(array4,(int)mem_one_part);
   Print("Array4 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",4.0*mem_one_part/1024/1024);

   res=ArrayResize(array5,(int)mem_one_part);
   Print("Array5 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",5.0*mem_one_part/1024/1024);

   uint gtc=GetTickCount();
   for(int i=0;i<mem_one_part;i++)
     {
      char ch=(char)rand();
      array1[i]=ch;
      array2[i]=ch;
      array3[i]=ch;
      array4[i]=ch;
      array5[i]=ch;
     }
//---
   printf("Spent time: %d ms",GetTickCount()-gtc);
  }

Получаю закономерный результат - невозможно распределить массив array3, т.к. память закончилась.

Затем раскомментирую строку, где указываю сколько сейчас доступно:

mem_free_mb=5300;//<--- Столько показывает 'Доступной' в диспетчере задач.

После этого скрипт выполняется успешно.

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

Сделайте пожалуйста, чтобы можно было это знать через TerminalInfoInteger.

 

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

Есть такое понятие - фрагментация памяти. Вы тут решили всю память на 5 фрагментов разделить - а нет у системы ни одного непрерывного фрагмента памяти требуемого Вам размера

 
Slawa:

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

Есть такое понятие - фрагментация памяти. Вы тут решили всю память на 5 фрагментов разделить - а нет у системы ни одного непрерывного фрагмента памяти требуемого Вам размера

1. Можно вначале узнать, что физически означает параметр TERMINAL_MEMORY_AVAILABLE ?

2. На счет фрагментов, я думаю, что этим должен заниматься менеждер памяти Windows а не программист.

Мне важно знать сколько я могу использовать в данный момент, например я хочу использовать 50 % от доступной памяти.

Другая реальная задача - это запрос CopyTicks. Если запрашивать больше тиков чем доступной памяти то получаем 'out of memory'.

 
Andrey Voytenko:

Другая реальная задача - это запрос CopyTicks. Если запрашивать больше тиков чем доступной памяти то получаем 'out of memory'.

как вариант, выгрузить данные в файл и брать оттуда необходимыми сегментами
 
coderex:
как вариант, выгрузить данные в файл и брать оттуда необходимыми сегментами

Это для меня медленно. Мне хочется все сделать через память. Собственно это и делается сейчас, только приходится вызывать GlobalMemoryStatusEx и узнавать размер доступной.


	          
 
Andrey Voytenko:

Поддерживаю.  Особенно остро эта проблема встаёт при оптимизации на облачных агентах, о возможностях которых ты вообще ничего не знаешь изначально.  Там определить реальный объём доступной памяти невозможно ни через MQL, ни через WinApi (т.к. вызовы dll запрещены).

Действительно непонятно, какой практический смысл тогда имеет TERMINAL_MEMORY_AVAILABLE ?   Зачем его было вводить, если нам от него ни горячо, ни холодно

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