Открытие файла и память

Страницы: 1
RSS
Открытие файла и память
 
Вот такой простенький код даёт 1 МБ прироста памяти в час. Некритично, но непонятно почему. Так и должно быть или я что-то делаю не так?
Код
local stopped = false

function OnStop(flag)
    stopped = true
end

function f11()
   local fpath = getScriptPath() .. "\\tos11.log"
   local f = io.open(fpath, "w+")
   f:close()
   f = nil
end

function main()
    while not stopped do
      f11()
      sleep(100)
    end
end
 
валерий, Как минимум, открывать и закрывать файл нужно в main, а не раз в 0.1 секунды. Ну и stopped вряд ли должен быть local.
 
валерий, да вроде все правильно, попробовал, чем меньше слип тем быстрее утекает. Как вариант периодически вызывать collectgarbage("collect")
 
Владимир, открывать и закрывать файл нужно там где нужно. Впрочем и в main те же яйца.
 
Игорь, так вопрос-то именно в том откуда здесь вообще может взяться garbage? Может  не догоняю?
 
Цитата
валерий написал:
Игорь, так вопрос-то именно в том откуда здесь вообще может взяться garbage? Может  не догоняю?
Кто бы знал. Я не спец в Луа.
Код
local fpath = "f:\\temp\\tos11.log"

function sleep(s)
  local ntime = os.time() + s
  repeat until os.time() > ntime
end

function f11()
   local f = io.open(fpath, "w+")
   if f then f:close() end
end

while true do
  f11()
  print(collectgarbage("count"))
  sleep(1)
end
Запустил такой код в Луа 5.3. - также потихоньку растет, но периодически чуть-чуть уменьшается видимо от сборки мусора.  
 
Цитата
Игорь написал:
Запустил такой код в Луа 5.3. - также потихоньку растет, но периодически чуть-чуть уменьшается видимо от сборки мусора.  
Но это не связано с f11(), там память растет и просто при вызове collectgarbage("count") :(  
 
Цитата
валерий написал:
так вопрос-то именно в том откуда здесь вообще может взяться garbage?
Так-то мусора полно. Объект файл один уже чего стоит, он ведь не кэшируется, открыли-закрыли - в мусор. Строка от getScriptPath сразу после использования - в мусор, fpath сразу после использования - в мусор. По-хорошему оно должно рано или поздно начисто все прибираться, иначе либо не успевает коллектор (вполне, кстати, возможно), либо где-то подтекает все-таки.
 
UPD. Не успевает коллектор. Вот так не течет
Код
local stopped = false

function OnStop(flag)
    stopped = true
end

function f11()
   local fpath = getScriptPath() .. "\\tos11.log"
   local f = io.open(fpath, "w+")
   f:close()
   f = nil
end

function main()
    while not stopped do
      f11()
      sleep(100)
      collectgarbage("step")
    end
end
 
А вот так сборщик работает хорошо - память сбрасывает:
Код
local stopped = false

function OnStop(flag)
    stopped = true
end

function f11()
   local fpath = getScriptPath() .. "\\tos11.log"
   local f = io.open(fpath, "w+")
   local fstr = string.rep("asd,qwe\n",500)
   f:write(fstr)
   f:flush()
   f:close()
   f = nil
   fstr = nil
end

function main()
    while not stopped do
      f11()
      sleep(100)
    end
end
Странно, но ему похоже не нравится именно, когда в файл ничего не пишешь.
 
Цитата
валерий написал:
Странно, но ему похоже не нравится именно, когда в файл ничего не пишешь.
Похоже что string.rep("asd,qwe\n",500) вызывает сборщик мусора, можно и не писать ничего. А обязательно файл открывать в функции? Может просто раз открыть а внутри f:flush делать - тогда и коллектор не нужен. Видимо сам io.open постоянно аллоцирует память.
 
Io.open создаёт в памяти объект -  дескриптор. Даже после закрытия этот объект остаётся в памяти до момента прохода сборщиком мусора.

обьект маленький, поэтому при стандартных настройках сборщика (200%) нет необходимости его чистить. Когда количество таких дескрипторов станет достаточно большим, сборщик их все уберет. Либо увеличивайте агрессивность сборщика, либо вызывайте его принудительно, но лучше не делайте вообще ничего, все будет хорошо и без вашего участия.
www.bot4sale.ru        t.me/bot4sale
 
Игорь, нет, дело не в string.rep. Если поставить единичку вместо 500, то сборщик опять не вызывается. Похоже дело в медленном накоплении мусора. Может как-то можно настроить сборщика на такое, но я погуглил и внятного разъяснения не нашёл. Так что или методом тыка подбирать или просто и грубо установить предел памяти для активации сборщика.
 
s_mike@rambler.ru, маленький, но без участия такой код за день вырастет с 40КБ до десятка МБ. Оно конечно некритично, но некрасиво. И не знаю сбросится ли память при пересменке, если квик не закрываешь.
Агрессивность сборщика это setstepmul
 
Довёл setstepmul до 700 - никакого эффекта.
 
Цитата
валерий написал:
Довёл setstepmul до 700 - никакого эффекта.
уменьшать надо )))
www.bot4sale.ru        t.me/bot4sale
 
s_mike@rambler.ru, довёл до 50. Те же яйца. Тут бы понимать принцип. А так в слепую.
 
Что интересно, если переменную удалить сразу после использования, то скрипт станет занимать больше памяти.
Код
local a = 0
print(collectgarbage("count"))  --> 23.4453125

Код
local a = 0
a = nil
print(collectgarbage("count"))  --> 23.453125
 
Цитата
Старатель написал:
Что интересно, если переменную удалить сразу после использования, то скрипт станет занимать больше памяти.
Код
   local  a  =   0 
 print (collectgarbage( "count" ))   --> 23.4453125   

Код
   local  a  =   0 
a  =   nil 
 print (collectgarbage( "count" ))   --> 23.453125   
рaзница в 8 байт. Как раз длина строчки a = nil )
www.bot4sale.ru        t.me/bot4sale
 
Цитата
s_mike@rambler.ru написал:
Цитата
Старатель написал:
Что интересно, если переменную удалить сразу после использования, то скрипт станет занимать больше памяти.
 
Код
      local   a   =     0  
 print (collectgarbage(  "count"  ))    --> 23.4453125      
 
 
Код
      local   a   =     0  
a   =     nil  
 print (collectgarbage(  "count"  ))    --> 23.453125      
 
рaзница в 8 байт. Как раз длина строчки a = nil )
a=nil - не удаляет переменную, а присваивает ей значение nil
а скрипт естественно длиннее на строку a=nil.
------------------------------------
Чудес не бывает, бывает лишь отсутствие знаний.
Страницы: 1
Читают тему (гостей: 1)
Наверх