QUIK и жор памяти, Проблема с памятью скриптов Qlua
Пользователь
Сообщений: Регистрация: 19.08.2022
07.10.2026 11:48:11
Случилось у меня такое интересное наблюдение :
Торговый робот на одной копии QUIK у одного брокера работает нормально, создаёт таблицу данных (43 мБ) и в течении всего времени работы поддерживает выделение памяти на этом уровне. Тот же самый работ на другой копии QUIK (той же версии 8.13.1.6), но у другого брокера испытывает скачки памяти (в таблицах Qlua) с интервалом приблизительно в 3-5 секунд : память растёт от 43мБ до 86 мБ, после чего опять возвращается к уровню 43мБ.
Никакой разницы в роботах или версиях QUIK нет. Все тяжелые вычисления проводятся с намного большей периодичностью (меньшей частотой), приблизительно раз в 30-60 секунд и в обязательном порядке сопровождаются вызовом сборщика мусора. В промежутках между вычислениями сборщик мусора не вызывается, а вся нагрузка это не частые запросы типа Poll (опрос) к котировкам и таблицам заявок. Среди колбэков только легковесные OnOrder(), OnTrnsReply() и всё. При этом на обоих экземплярах QUIK ведётся торговля другими торговыми алгоритмами приблизительно с одинаковой интенсивностью, то есть все обработчики вызываются одинаково регулярно и их выполнение точно не занимает в памяти 40 мБ.
Подскажите, в чём может быть проблема?!
QUIK clients support
Сообщений: Регистрация: 11.08.2025
07.10.2026 17:08:24
Здравствуйте.
Прежде всего рекомендуем применить оптимальные настройки Рабочего места QUIK, которые указаны в теме: Так же рекомендуем обновить версию РМ QUIK до актуальной 13.2 и понаблюдать за его работой некоторое время.
Пользователь
Сообщений: Регистрация: 19.08.2022
07.10.2026 18:28:27
Это всё уже сделано и объемы данных минимизированны в обоих копиях КВИК. Тем более одно дело память КВИК (300мБ-1500мБ), другое дело память Lua скрипта, которая почему-то засоряется.
Пользователь
Сообщений: Регистрация: 30.01.2015
07.10.2026 18:31:12
Цитата
Кот написал: Случилось у меня такое интересное наблюдение :
Торговый робот на одной копии QUIK у одного брокера работает нормально, создаёт таблицу данных (43 мБ) и в течении всего времени работы поддерживает выделение памяти на этом уровне. Тот же самый работ на другой копии QUIK (той же версии 8.13.1.6), но у другого брокера испытывает скачки памяти (в таблицах Qlua) с интервалом приблизительно в 3-5 секунд : память растёт от 43мБ до 86 мБ, после чего опять возвращается к уровню 43мБ.
Никакой разницы в роботах или версиях QUIK нет. Все тяжелые вычисления проводятся с намного большей периодичностью (меньшей частотой), приблизительно раз в 30-60 секунд и в обязательном порядке сопровождаются вызовом сборщика мусора. В промежутках между вычислениями сборщик мусора не вызывается, а вся нагрузка это не частые запросы типа Poll (опрос) к котировкам и таблицам заявок. Среди колбэков только легковесные OnOrder(), OnTrnsReply() и всё. При этом на обоих экземплярах QUIK ведётся торговля другими торговыми алгоритмами приблизительно с одинаковой интенсивностью, то есть все обработчики вызываются одинаково регулярно и их выполнение точно не занимает в памяти 40 мБ.
Подскажите, в чём может быть проблема?!
Посмотрите сколько памяти занимает каждый вариант QUIK
Посмотрите сколько памяти занимает каждый вариант QUIK
Тот который не перегружает занимает 1200 мБ, другой, который перегружает 1870 мБ.
Пока что создаётся впечатление, что это работа OnTrnsReply(reply), так как перегрузка памяти идёт именно в моменты активной торговли другими системами.
Соответственно встаёт вопрос - как с этим бороться? Может быть стоит прописать reply= { } чтобы чистить память сразу из Коллбэка? Потому что никакой сложной обработки у меня нет, фактически все завершается первой строчкой : if reply.account~=Account then return; end; Да и в остальном коде только поиски по тексту ошибки. Мегабайтам там уходить некуда!
Посмотрите сколько памяти занимает каждый вариант QUIK
Тот который не перегружает занимает 1200 мБ, другой, который перегружает 1870 мБ.
Пока что создаётся впечатление, что это работа OnTrnsReply(reply), так как перегрузка памяти идёт именно в моменты активной торговли другими системами.
Соответственно встаёт вопрос - как с этим бороться? Может быть стоит прописать reply= { } чтобы чистить память сразу из Коллбэка? Потому что никакой сложной обработки у меня нет, фактически все завершается первой строчкой : if reply.account~=Account then return; end; Да и в остальном коде только поиски по тексту ошибки. Мегабайтам там уходить некуда!
посмотрите на что Вы подписаны и сделайте число инструментов в подписке одинаковым Сделайте одинаковое число открытых графиков
Пользователь
Сообщений: Регистрация: 30.01.2015
08.10.2026 13:00:13
Предположу ,что проблема в разном объеме в VMLUA свободной памяти. Поэтому сборщик мусора работает по-разному.
Пользователь
Сообщений: Регистрация: 19.08.2022
08.10.2026 14:59:49
Цитата
nikolz написал: Предположу ,что проблема в разном объеме в VMLUA свободной памяти. Поэтому сборщик мусора работает по-разному.
Проблема решена. Код :
for iord=lastact,N do local tab=getItem('orders',iord); -- получаем заявку i if tab~=nil then if tab.account==acc then if bit.band(tab.flags,0x1)==0x1 then ... end; end; end; end;
Перебирал большое число заявок (все) и засорял память, хоть и срабатывал сравнительно редко. До сих пор не понимаю как в qlua сделать локальную переменную массива (таблицы), чтобы при её обработке в цикле не возникало жора памяти?!
QUIK clients support
Сообщений: Регистрация: 11.08.2025
09.10.2026 15:19:12
Добрый день.
Ранее вы говорили о версии РМ QUIK 8.13.1.6. Подскажите, какая версия Рабочего места используется в данный момент?
Пользователь
Сообщений: Регистрация: 27.01.2017
09.10.2026 16:06:42
Т.к. это в цикле, то получение данных таблицы - это каждый раз выделение памяти. local tab=getItem('orders',iord);
Выйдет из цикла и функции, делающее это, сборщик удалит и освободит память.
for iord=lastact,N do local tab=getItem('orders',iord); -- получаем заявку i if tab~=nil then if tab.account==acc then if bit.band(tab.flags,0x1)==0x1 then ... end; end; end; end;
Перебирал большое число заявок (все) и засорял память, хоть и срабатывал сравнительно редко. До сих пор не понимаю как в qlua сделать локальную переменную массива (таблицы), чтобы при её обработке в цикле не возникало жора памяти?!
в версии 5.3 и 5.4 есть логические операции вместо этого: if bit.band(tab.flags,0x1)==0x1 можно писать это: if tab.flags&1==1 --------------------------------------- измените алгоритм программы. Создайте массив активных заявок. И не надо будет много перебирать
Пользователь
Сообщений: Регистрация: 22.02.2023
10.10.2026 20:47:06
Цитата
Кот написал: for iord=lastact,N do local tab=getItem('orders',iord); -- получаем заявку i if tab~=nil then if tab.account==acc then if bit.band(tab.flags,0x1)==0x1 then ... end; end; end; end;
Если сначала найти индексы всех интересующих заявок, и в цикле извлекать только их, то памяти может потребоваться меньше.
Код
local function Fnd(f,a)
return f & 1 == 1 and a == acc
end
local aOrd = SearchItems("orders", lastact, N, Fnd, "flags, account") or {}
for _, iord in ipairs(aOrd) do
local tab = getItem("orders",iord)
--...
end
написал: for iord=lastact,N do local tab=getItem('orders',iord); -- получаем заявку i if tab~=nil then if tab.account==acc then if bit.band(tab.flags,0x1)==0x1 then ... end; end; end; end;
Если сначала найти индексы всех интересующих заявок, и в цикле извлекать только их, то памяти может потребоваться меньше.
Код
local function Fnd (f,a)
return f & 1 = = 1 and a = = acc
end
local aOrd = SearchItems ( "orders" , lastact, N, Fnd, "flags, account" ) or {}
for _, iord in ipairs(aOrd) do
local tab = getItem ( "orders" ,iord)
--...
end
в начале активные заявки ищутся один раз что не критично для дальнейших расчетов Но если потом выставляются новые заявки то вопрос именно в том как они находятся Если их искать по таблице заявок QUIK то все будет ровно так как написал автор темы ------------------------ А чтобы так не было надо делать свою таблицу активных заявок Сначала ее заполняем по таблице заявок QUIK а потом работаем с ней по колбеку заявок