On a linux server I'm using Chrome/Selenium with Xvfb in a python script. Sometimes the script crashes for other reason and thus, according to what I see in the dashboard of digital ocean, the ram consumption of "Xvfb" increases up to almost 80% eventually, over time. However, the ram increase isn't necessarily due to the script being crashed, but it might be because of an wrong of releasing Xvfb in general.
Here's what I have relevant to xvfb
from pyvirtualdisplay import Display
..........
display = Display(visible=0, size=(800, 600))
display.start()
//it can crash here doing other things
display.sendstop()
- Am I releasing Xvfb properly in the first place?
- When it crashes, does Xvfb get released automatically or not?
- Should I wrap my code into try ... except to be able properly release Xvfb?
Short answer is that
display.sendstop()
is not being called if your code crashes where you showed.I think the most 'pythonic' way to achieve what you want would be to use the
Display
as a context manager, meaning that you do not need to wrap all of your code in a try/catch but you get the same benefit. Something like this should work:EDIT: The reason that the call to the stop method is important in this particular case (and why you are almost certainly right about the memory leak) is because your code is spawning an Xvfb subprocess to act as the virtual display. The stop method kills this subprocess and so if it is never called the subprocess remains running & is reparented onto the init process. There is some more information on this here (section 'Zombie and Orphan Processes').
I was able to check how this works using this simple bit of code:
I then ran
pstree -sA $(pgrep Xvfb)
in my shell (to show the process tree of the Xvfb process) before and after the python script crashed.Before the crash we can see that the parent process of the Xvfb process is python (whose parent is my shell, whose parent is my terminal emulator etc.):
After the python script crashes the process has now been reparented onto the init process (in my case this is systemd but in your case it may be some other init system).