2016-12-18 11 views
1

Linuxサーバーでは、私はXvfbとPythonスクリプトでChrome/Seleniumを使用しています。スクリプトが別の理由でクラッシュすることがあるので、デジタル海洋のダッシュボードに表示されているように、「Xvfb」のラム消費は最終的にはほぼ80%まで増加します。しかし、ラムの増加は必ずしもスクリプトがクラッシュしたためではありませんが、一般にXvfbをリリースするのは間違っている可能性があります。ここでPythonスクリプトでメモリリークが発生しました.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に関連してい何ですか?
  • クラッシュすると、Xvfbが自動的に解放されるのですか?
  • Xvfbを適切にリリースできる点を除いて、私のコードを試してください。

答えて

2

あなたが示した場所でコードがクラッシュした場合、display.sendstop()は呼び出されません。

Displaycontext managerとして使用するのが最も望ましいと思うのですが、try/catchですべてのコードをラップする必要はありませんが、同じ利点があります。このような何か作業をする必要があります:

import pyvirtualdisplay 

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

EDIT:あなたのコードが産卵されているため、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() 

私は、Pythonスクリプトの前と後(Xvfbのプロセスのプロセスツリーを表示するには)私のシェルでpstree -sA $(pgrep Xvfb)を走りました墜落したPythonスクリプトがクラッシュした後

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

:我々はXvfbのプロセスの親プロセスが(その親など、私の端末エミュレータである親が私のシェルである、)のpythonであることがわかりますクラッシュする前に

プロセスがinitプロセスに親子化されました(私の場合、これはsystemdですが、あなたの場合は他のinitシステムかもしれません)。

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

短い答えは、表示された場所でコードがクラッシュした場合、display.sendstop()が呼び出されないということです。スクリプトはクラッシュしているので、OSは開いているハンドラをすべて閉じないでください。 – Saurabh

+0

'短い答えは、表示された場所でコードがクラッシュした場合にdisplay.sendstop()が呼び出されないということです。' - そうでないとします。スクリプトがクラッシュしたため、OSは開いているすべてのハンドラを閉じないのですか? – Saurabh

+0

私が作った編集がこれをより良く説明してくれることを願っています。 答えはいいえ - PyVirtualDisplayは、スクリプトが終了した後も残っているサブプロセスを作成しています。 – joelnb