内存在python脚本中泄漏,Xvfb被怀疑

时间:2016-12-18 16:54:11

标签: python linux selenium xvfb

在Linux服务器上,我在python脚本中使用带有 Xvfb 的Chrome / Selenium。有时脚本因其他原因而崩溃,因此,根据我在数字海洋仪表板中看到的情况,随着时间的推移,“Xvfb”的内存消耗最终会增加到近80%。但是,ram增加不一定是由于脚本崩溃,但可能是因为一般情况下释放Xvfb是错误的。

这是我与xvfb相关的内容

    from pyvirtualdisplay import Display
    ..........
    display = Display(visible=0, size=(800, 600))
    display.start()


    //it can crash here doing other things

    display.sendstop()
  • 我是否首先正确释放Xvfb?
  • 当它崩溃时,Xvfb会自动释放吗?
  • 我应该将我的代码包装成try ...除了能够正确释放Xvfb吗?

1 个答案:

答案 0 :(得分:3)

简短回答是,如果您的代码在您展示的位置崩溃,则不会调用display.sendstop()

我认为实现你想要的最“pythonic”方式是使用Display作为context manager,这意味着你不需要在try /中包装所有代码赶上,但你得到同样的好处。这样的事情应该有效:

import pyvirtualdisplay

with pyvirtualdisplay.Display(visible=0, size=(800, 600)):
    // it can crash here doing other things

编辑:在这种特殊情况下调用stop方法很重要的原因(以及为什么你几乎肯定对内存泄漏是正确的)是因为你的代码产生了一个Xvfb子进程来充当虚拟显示。 stop方法终止了这个子进程,所以如果它从未被调用,那么子进程仍在运行&被重新定位到init进程。有关此here的更多信息(“僵尸和孤儿进程”部分)。

我能够使用这一段简单的代码检查其工作原理:

import time
from pyvirtualdisplay import Display

display = Display(visible=0, size=(800, 600))
display.start()

print('About to sleep')
time.sleep(20)

raise Exception('Oh noes!')

display.stop()

然后我在我的shell中运行pstree -sA $(pgrep Xvfb)(以显示Xvfb进程的进程树)在python脚本崩溃之前和之后。

在崩溃之前,我们可以看到Xvfb进程的父进程是python(其父代是我的shell,其父代是我的终端模拟器等):

systemd---xfce4-terminal---zsh---python---Xvfb-+-{llvmpipe-0}
                                               |-{llvmpipe-1}
                                               |-{llvmpipe-2}
                                               `-{llvmpipe-3}

在python脚本崩溃后,该进程现已被重新分配到init进程(在我的情况下,这是systemd,但在你的情况下,它可能是一些其他的init系统)。

systemd---Xvfb-+-{llvmpipe-0}
               |-{llvmpipe-1}
               |-{llvmpipe-2}
               `-{llvmpipe-3}