1. При аварийном завершении работы скрипта не удаляется окно(таблица AllocTable()) которое было создано в квике
2. Не освобождается память по коду ниже, при использовании SetEmptyCallback очищается нормально
Код
function OnCandle(index)
end
function OnStop()
is_run = false
end
function main()
collectgarbage ("setpause",50)
collectgarbage ("setstepmul",300)
class="SPBFUT"
name="SiM0"
ds_chan=CreateDataSource(class, name, INTERVAL_M1)
ds_chan:SetUpdateCallback(OnCandle)
is_run=true
while is_run do
local t = ""
local a = tostring(getInfoParam("SERVERTIME"))
for s in a:gmatch('%d+') do
t=t..s
end
--sleep(15)
end
ds_chan:Close()
end
Андрей написал: 1. При аварийном завершении работы скрипта не удаляется окно(таблица AllocTable()) которое было создано в квике
Пока не вызван DestroyTable таблица не должна удаляться. А он не может быть вызван по причине аварийного завершения работы скрипта. В старых версиях также было.
Цитата
Андрей написал: 2. Не освобождается память по коду ниже, при использовании SetEmptyCallback очищается нормально
Поясните подробней как проводилось исследование, как был сделан вывод?
если запустить этот код то память постоянно ростет, смотрю по диспетчеру задач виндовс. Если заменить SetUpdateCallback на SetEmptyCallback то память в диспетчере задач не ростет. Сборщик мусора не помогает. Возможно не очищается переменная t
В итоге когда квик 8.5 с запущенным данным скриптом выедает полностью всю память, память очищается, и сново начинает заполнятся, затем на второй и третий раз полного заполнения памяти квик падает без дампа. Можно использовать sleep(15) тогда просто память медленнее растет. В 7 квике такого сильного роста памяти нет.
ниже приведен код когда память не растет(заменен SetUpdateCallback на SetEmptyCallback)
Код
function OnStop()
is_run = false
end
function main()
collectgarbage ("setpause",0)
collectgarbage ("setstepmul",600)
class="SPBFUT"
name="SiM0"
ds_chan=CreateDataSource(class, name, INTERVAL_M1)
ds_chan:SetEmptyCallback()
is_run=true
while is_run do
local t = ""
local a = tostring(getInfoParam("SERVERTIME"))
for s in a:gmatch('%d+') do
t=t..s
end
--sleep(15)
end
ds_chan:Close()
end
Андрей написал: В итоге когда квик 8.5 с запущенным данным скриптом выедает полностью всю память, память очищается, и сново начинает заполнятся, затем на второй и третий раз полного заполнения памяти квик падает без дампа. Можно использовать sleep(15) тогда просто память медленнее растет. В 7 квике такого сильного роста памяти нет.
Проблема изучается. Постараемся в ближайшее время дать ответ.
Действительно есть ошибка работы SetUpdateCallback приводящая к остановке работы garbage collector. Что в свою очередь приводит к повышенному потреблению RAM.
Действительно есть ошибка работы SetUpdateCallback приводящая к остановке работы garbage collector. Что в свою очередь приводит к повышенному потреблению RAM.
Мы исправим ошибку в ближайшем обновлении ПО.
Приносим извинения за доставленные неудобства.
Будем надеяться хотя бы в этом году это произойдет;)
Данная ошибка будет исправлена ДО июня, когда все обязаны перейти на 8.5? Сейчас 8.5 пользоваться нельзя, QUIK падает через 1-2 дня просто на ровном месте без дампа.
Причем в скриптах CreateDataSource вообще не используется, т.е. все значения берутся напрямую с графиков. Скрипт отработан на 7 и 8-х версиях и работает там без ошибок месяцами (естественно он исправлен под синтаксис 5.3), никаких внешних библиотек не используется в принципе.
Александр М написал: Данная ошибка будет исправлена ДО июня, когда все обязаны перейти на 8.5? Сейчас 8.5 пользоваться нельзя, QUIK падает через 1-2 дня просто на ровном месте без дампа.
Причем в скриптах CreateDataSource вообще не используется, т.е. все значения берутся напрямую с графиков. Скрипт отработан на 7 и 8-х версиях и работает там без ошибок месяцами (естественно он исправлен под синтаксис 5.3), никаких внешних библиотек не используется в принципе.
У меня тоже квик упал через три дня тестов без дампа, пытался найти почему. Но теперь уже не буду спасибо за сообщение.
Действительно есть ошибка работы SetUpdateCallback приводящая к остановке работы garbage collector. Что в свою очередь приводит к повышенному потреблению RAM.
Мы исправим ошибку в ближайшем обновлении ПО.
Приносим извинения за доставленные неудобства.
О! А я на Papallels матом обижался за поджор памяти. Давайте ребята пачте поскорее.
Андрей написал: 1. При аварийном завершении работы скрипта не удаляется окно(таблица AllocTable()) которое было создано в квике
2. Не освобождается память по коду ниже, при использовании SetEmptyCallback очищается нормально
Код
function OnCandle (index)
end
function OnStop ()
is_run = false
end
function main ()
collectgarbage ( "setpause" , 50 )
collectgarbage ( "setstepmul" , 300 )
class = "SPBFUT"
name = "SiM0"
ds_chan = CreateDataSource (class, name, INTERVAL_M1)
ds_chan: SetUpdateCallback (OnCandle)
is_run = true
while is_run do
local t = ""
local a = tostring( getInfoParam ( "SERVERTIME" ))
for s in a:gmatch( '%d+' ) do
t = t .. s
end
--sleep(15)
end
ds_chan: Close ()
end
Добрый день,
Описанная в данном инциденте ошибка была исправлена в версии 8.5.2 терминала QUIK. Рекомендуем вам обновить версию программы.
Старатель написал: При остановке скрипта в результате ошибки память не освобождается.
Еще со старого луа осталось. Что характерно, при повторном запуске того же скрипта - добивается. Но это часто слишком поздно, если финализеры используются. Пытался обойти так
Код
local function safecall(fn, ...)
local a
if nil == arg then a = nil else a = unpack(arg) end
local s, e = pcall(fn, a);
if not s then
_G = nil
collectgarbage()
error(e)
end
end
OnI nit = function()
safecall(function()
message("OnInit")
--error("error in OnInit")
end)
end
main = function()
safecall(function()
message("main")
local ltbl = {}
setmetatable(ltbl, { __gc = function() message("ltbl finalizer") end })
error("error in main")
end)
end
Но это ж жесть, колбеки через pcall пропускать. Вот то, что у меня в safecall при ошибке, надо и в квике при ошибке делать.
Подтверждаю наличие в 8.5.2 и во всех предках. Другой (возможно, более наглядный) вариант тестового скрипта не раз уже приводил:
Код
-- global table
gtbl = {}
setmetatable(gtbl, { __gc = function() message("gc global level") end })
-- chunk-level table
local stbl = {}
setmetatable(stbl, { __gc = function() message("gc chunk level") end })
function OnInit()
message("OnInit")
-- error("OnInit error")
end
function main()
message("main")
local ltbl = {}
setmetatable(ltbl, { __gc = function() message("gc function level") end })
error("main error")
end
При первом запуске квик показывает ошибку в мейне, сборки мусора нет. Если запустить его снова, сначала отработают все финализаторы в положенном порядке. Сам факт, что стейт со всеми глобалами переживает скрипт, уже на мысли наводит.
Egor Zaytsev написал: Мы исправим ошибку в ближайшем обновлении ПО.
Радостно слышать. Немного напрягает уточнение "синтаксических". На этом этапе подчищать еще особо и нечего, интересно именно когда скрипт уже поехал и насоздавал всякого.
Это, похоже, последняя ошибка в qlua на уровне собственно языка.
Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK. Рекомендуем вам обновить версию программы. Приносим извинения за причиненные неудобства.
Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK. Рекомендуем вам обновить версию программы. Приносим извинения за причиненные неудобства.
а можно продолжить работать на версии Квик 7 после ввода 19-значных номеров заявок?
Evgeniy Karnaukhov написал: Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK.
Уже опробовал, при ошибке из мейна действительно теперь выходим с очисткой. Это уже позволяет сделать нормальную обработку ошибок в скрипте, до того задача была неразрешимой без костылей. Спасибо всем принявшим участие в исправлении.
Однако, если бросить ошибку в теле скрипта или в OnInit, по-прежнему выпадем без очистки. С этим можно жить, конечно, отложить ошибку до мейна ровно три строчки, но непорядочек все же. Тем более, в отличие от ошибок в колбеках, в этот момент мейн еще не создан, следовательно, жестко прибивать поток мейна не придется, тут теоретически можно допилить до красоты.
Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK. Рекомендуем вам обновить версию программы. Приносим извинения за причиненные неудобства.
а можно продолжить работать на версии Квик 7 после ввода 19-значных номеров заявок?
Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK. Рекомендуем вам обновить версию программы. Приносим извинения за причиненные неудобства.
а можно продолжить работать на версии Квик 7 после ввода 19-значных номеров заявок?
я понимаю, что в данной ветке, ну а технически в Квик 7 будет возможность снять заявку вручную через меню терминала правой кнопкой мыши "Снять заявку" ?
Описанная в данном инциденте ошибка была исправлена в версии 8.6.0 терминала QUIK. Рекомендуем вам обновить версию программы. Приносим извинения за причиненные неудобства.
а можно продолжить работать на версии Квик 7 после ввода 19-значных номеров заявок?
я понимаю, что в данной ветке, ну а технически в Квик 7 будет возможность снять заявку вручную через меню терминала правой кнопкой мыши "Снять заявку" ?
Здравствуйте.
Да, в 7 версии QUIK такая возможность присутствует.
Anton написал: Однако, если бросить ошибку в теле скрипта или в OnInit, по-прежнему выпадем без очистки. С этим можно жить, конечно, отложить ошибку до мейна ровно три строчки, но непорядочек все же. Тем более, в отличие от ошибок в колбеках, в этот момент мейн еще не создан, следовательно, жестко прибивать поток мейна не придется, тут теоретически можно допилить до красоты.
Можете привести пример кода на котором проблема воспроизводится?
Sergey Gorokhov написал: Можете привести пример кода на котором проблема воспроизводится?
Да, конечно. Проверил еще раз на 8.6.0.97 только что, все как было, запускаем - получаем просто ошибку, запускаем повторно - получаем сначала все финализаторы, потом ошибку.
Код
local run = true
-- global table
tgl = {}
setmetatable(tgl, { __gc = function() message("global __gc") end })
-- chunk-level table
local tcl = {}
setmetatable(tcl, { __gc = function() message("chunk-level __gc") end })
function OnStop()
run = false
end
function OnInit()
-- function-level table
local tfl = {}
setmetatable(tfl, { __gc = function() message("function-level __gc") end })
do
-- block-level table
local tbl = {}
setmetatable(tbl, { __gc = function() message("block-level __gc") end })
-- now raise an error
error("error from OnInit")
end
end
function main()
while run do
sleep(1000)
end
end
Sergey Gorokhov написал: Можете привести пример кода на котором проблема воспроизводится?
Да, конечно. Проверил еще раз на 8.6.0.97 только что, все как было, запускаем - получаем просто ошибку, запускаем повторно - получаем сначала все финализаторы, потом ошибку.
Код
local run = true
-- global table
tgl = {}
setmetatable(tgl, { __gc = function () message ( "global __gc" ) end })
-- chunk-level table
local tcl = {}
setmetatable(tcl, { __gc = function () message ( "chunk-level __gc" ) end })
function OnStop ()
run = false
end
function OnInit ()
-- function-level table
local tfl = {}
setmetatable(tfl, { __gc = function () message ( "function-level __gc" ) end })
do
-- block-level table
local tbl = {}
setmetatable(tbl, { __gc = function () message ( "block-level __gc" ) end })
-- now raise an error
error( "error from OnInit" )
end
end
function main ()
while run do
sleep ( 1000 )
end
end
Добрый день, Описанная в данном инциденте ошибка была исправлена в версии 8.7.1 терминала QUIK. Рекомендуем вам обновить версию программы.
Sergey Gorokhov написал: Можете привести пример кода на котором проблема воспроизводится?
Да, конечно. Проверил еще раз на 8.6.0.97 только что, все как было, запускаем - получаем просто ошибку, запускаем повторно - получаем сначала все финализаторы, потом ошибку.
Код
local run = true
-- global table
tgl = {}
setmetatable(tgl, { __gc = function () message ( "global __gc" ) end })
-- chunk-level table
local tcl = {}
setmetatable(tcl, { __gc = function () message ( "chunk-level __gc" ) end })
function OnStop ()
run = false
end
function OnInit ()
-- function-level table
local tfl = {}
setmetatable(tfl, { __gc = function () message ( "function-level __gc" ) end })
do
-- block-level table
local tbl = {}
setmetatable(tbl, { __gc = function () message ( "block-level __gc" ) end })
-- now raise an error
error( "error from OnInit" )
end
end
function main ()
while run do
sleep ( 1000 )
end
end
Добрый день, Описанная в данном инциденте ошибка была исправлена в версии 8.7.1 терминала QUIK. Рекомендуем вам обновить версию программы.
1. При закрытии data_source память не освобождается, если был назначен SetUpdateCallback Код:
Скрытый текст
Код
local run = true
function OnStop()
run = nil
end
function main()
local function cb(index) end
local ds
while run do
ds = CreateDataSource(class, sec_code, INTERVAL_M1)
ds:SetUpdateCallback(cb)
sleep(500)
ds:Close()
ds = nil
collectgarbage("collect")
sleep(500)
end
collectgarbage("collect")
message(string.format("Memory: %.1f Mb", collectgarbage("count") / 1024))
end
Если убрать строку с SetUpdateCallback или заменить на SetEmptyCallback, память не растёт.
2. Если при загрузке модулей возникает ошибка, то библиотеки из памяти не выгружаются. Код:
Скрытый текст
Код
require(mod1)
require(mod2) -- Тут возникает ошибка загрузки модуля
-- mod1 выгружен не будет.
function main()
...
end
Надо делать так, как надо. А как не надо - делать не надо.
Действительно в ПО QLUA есть некорректная обработка ошибок загрузки скриптов, приводящая к незакрытию Lua-стейтмента. Мы исправим ошибку в очередном обновлении ПО. Приносим извинения за причинённые неудобства.
Действительно, в ПО QLUA есть ошибка закрытия источников данных. Мы исправим её в очередном обновлении ПО. Приносим извинения за причинённые неудобства.