Just a suggestion…
since our setup is quite complex, we load a lot of images and we are very cautious, in order to be on the safe side we were thinking about restarting info-beamer (standalone) periodically so as to avoid memory leakages due to our node.lua and out of memory errors due to poor resource management on our part.
I know it’s not good programming practice but given the situation (imminent exhibition, first public display of our node.lua setup… it has a reason to be. It’s just a safety net.
Moreover the same solution can be used just when loading images gives an error (for example) or other well known and documented situations.
We are of course talking about info-beamer standalone.
The problem is, between shutting down and restarting info beamer there’s a black screen for around 1 second (due to resource loading mostly)… not terrible but we were thinking around it.
We came up with this solution:
0) display the background image menu.png to raspberry framebuffer via fbv menu.png
start info beamer service with the variable export INFOBEAMER_TRANSPARENT=1
on certaing given transitions of the UI, issue a sys command (still to be investigated) that will do service -d /service/info-beamer; service -u /service/info-beamer
the service will go down and up, and while loading the node, it will be transparent and display the menu.png file. If the first image displayed by our node is the same, the trick is done and it’s almost impossible to notice.
We have dona proof of concept and it works.
Still open:
2) issue a sys command from LUA
0) with fbv the image does not go in overscan so it’s kinda shrinked and doesn’t reach the border of our monitor
Unless you accidentally keep references to image/video object alive (by putting them in some table for example), the Lua garbage collector will eventually clean up everything and no system memory is leaked ever. Of course avoiding such resource leaks might be tricky and normally you have to manually :dispose() object to have more control over when such resources are actually free’d. Otherwise free’ing might be deferred until the garbage collector decides to dispose them.
(You can see currently loaded object by sending a SIGUSR2 signal to info-beamer. Just run pkill -usr2 info-beamer)
There is a way to force the Lua GC to collect garbage after every frame. This means that if you have code like:
image = nil
the GC will immediately :dispose() that image once the current frame rendering is done (by default the then unreachable image object is still kept around for a bit until the GC kicks in). As this is more CPU intensive, it’s disabled by default. You can enable that with node.set_flag("slow_gc", false) (see https://info-beamer.com/blog/understanding-garbage-collection).
You can’t run system commands from info-beamer. There is no os.execute. The code is sandboxed by design.
If you have little other arm userland stuff running, increasing the gpu_mem to 512 or even more might also be possible to avoid errors in situations when too many images are required to be loaded at once.
Sorry Florian, I’ve corrected my post. Of course info-beamer does not leak. It’s our code that could maintain reference to unused images for a long time because of sloppy/naive programming on our part.
We prefer to handle disposing by hand and not run the CPU intensive garbage collector every frame.
Thanks for pointing out that our LUA code is sandboxed. It’s a nice thing.
As per the gpu_mem what is the upper limit of this memory? Is it a shared memory with the CPU i suppose? We don’t have anything else running a part from the python service daemon that reads user inputs and relays them to the LUA node.
Exactly. If you don’t have a lot otherwise going on. 256MB might well be more than enough. Of course that then also reduces the filesystem cache which might speed up loading images if they have been loaded before, but that’s probably not really noticeable
It’s not too bad actually. You might give it a try and see if the CPU goes up. I suspect you might not really see a difference.
KiB Mem : 766744 total, 61052 free, 68180 used, 637512 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 640280 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4821 root 20 0 254524 29680 15256 S 9.9 3.9 0:36.67 info-beamer
4826 root 20 0 25920 13472 6000 S 1.3 1.8 0:02.04 python
4881 root 20 0 8208 3344 2812 R 1.3 0.4 0:03.37 top
1683 pi 20 0 11660 1740 976 S 1.0 0.2 1:31.62 sshd
59 root 1 -19 0 0 0 S 0.3 0.0 7:18.36 vchiq-slot/0
1 root 20 0 9520 3988 2968 S 0.0 0.5 0:21.75 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.11 kthreadd
I’ve never relly understood top. Used + avail memory gives me more than the 1Giga present Now I have 256 MB allocated to GPU. Do you think moving up to 384 for example could be a problem? … the %MEM percentages are risible. Indeed your engine is perfect!
Right now we have preloaded in cache 6 o 7 full HD or so images…
The output is buff + used + free == total. I guess used is memory that’s not memory mapped from somewhere but actually used. buff is probably mostly file system cache. The more that’s is the better as IO doesn’t have to touch the SD card.
Ok… but should’nt a Raspberry Pi3 (+ or not plus) have 1GB of Ram? So total makes sense per se… but not regarding overall memory
anyway now that we have cleaned up our code I will ramp up GPU mem and test it for the w.e. Thanks!
It has, but that’s split between GPU and ARM memory. That’s what the firmware gpu_mem parameter sets up before Linux even starts. So Linux only sees 1GB - gpu_mem. In theory there was an option to make that split dynamic (keyword is cma), but IIRC that didn’t work too well in the tests I’ve done a few years ago.