Hi,

On 01.01.2014 19:42, Csaba Dunai wrote:
> Uli Schlachter <psychon <at> znc.in> writes:
[...]
> Thanks for the quick reply. Unfortunately my problem is still not solved. My
> point is not only to make the wibox disappear but also to free up the memory
> it occupies.
> 
> I have run the following test:
> 
> 1) run awesome as is: used ~1% of my RAM
> 
> 2) run awesome and make 10000 wiboxes: used ~8% of my ram
> 
> [CODE]
> 
> listOfWiboxes = {}
> for i = 1,10000 do
>   listOfWiboxboxes[i] = wibox({})
> end
> 
> [END CODE]
> 
> 3) run awesome, make 10000 wiboxes and then remove them: used ~8% of my ram.
> 
> [CODE]
> 
> listOfWiboxes = {}
> for i = 1,10000 do
>   listOfWiboxes[i] = wibox({})
> 
>   listOfWiboxes[i].visible = false
>   listOfWiboxes[i] = nil  -- (I've also tried by leaving this line away)
> end
> 
> [END CODE]
> 
> As you can see setting the visible field to false isn't enough to free the
> memory. Is there a way to solve this issue?
> 
> Thanks again for your effort.
> 
> Best Regards

I did my own experiments. Instead of looking at memory usage in top, I asked
lua's collectgarbage() function for an estimation of the memory used. This
should result in more exact numbers.

Also, since the wibox was never visible, the ".visible = false" isn't necessary.
Sorry for suggesting it.

TL;DR: Seems to work fine here.

Due to the redraw optimizations (wiboxes are redrawn only some time after
something notices they need a redraw), wiboxes cannot be garbage collected while
a redraw is pending. I solve this in the code below by starting a timer that
fires after one second. Also, for some reason that I don't understand, I have to
run the garbage collector twice.

My (ugly!) code:

local wibox = require("wibox")
collectgarbage("collect")
print(collectgarbage("count"))
local foo = {}
for i = 1,100 do
  table.insert(foo, wibox({}))
end
collectgarbage("collect")
print(collectgarbage("count"))
foo = nil
collectgarbage("collect")
print(collectgarbage("count"))
local t = timer({timeout = 1})
t:connect_signal("timeout", function()
collectgarbage("collect")
   collectgarbage("collect")
   print(collectgarbage("count"))
   awesome.quit()
end)
t:start()

The code's output when I use this as awesome's rc.lua:

814.64453125
2122.6962890625
2107.4267578125
848.3525390625

What this means: Right after startup and loading the wibox library, 814 KiB is
used (I am not sure if this really is measured in KiB, but I will just assume
so). After 100 wiboxes are created, this jumps to 2122 KiB. Right after the "foo
= nil" line, the wiboxes should be garbage collectable, but due to the redraw
magic mentioned above, there are still internal references to them. Thus, the
garbage collector only manages to free 15 KiB of memory (2122-2107).

After a second, the timer runs. For some reason that I don't understand, I have
to run the garbage collector here twice. This took me way too long to notice.
Weird. :-(

Anyway, in the second since their creation, the needed redraws were run and the
wiboxes can be garbage collected. And indeed, the memory usage drops down to 848
KiB. This is still 34 KiB more than right after startup, but I will assume that
this is (at least partly) due to the timer object that cannot be garbage 
collected.

So the wiboxes are deleted without any issue here.

Cheers (and a happy new year),
Uli
-- 
"In the beginning the Universe was created. This has made a lot of
 people very angry and has been widely regarded as a bad move."

-- 
To unsubscribe, send mail to [email protected].

Reply via email to