2011-01-04 19 views
5

デバッグの2日後、私は自分のタイムホッグ、つまりPythonのガベージコレクタを打ち砕いた。
私のアプリケーションは、多くのオブジェクトをメモリに保持しています。それはうまくいく。
GCは通常のラウンドを実行します(私は(700、10、10)のデフォルトしきい値でプレイしていません)。
重要なトランザクションの途中で、第2世代スイープが始まり、〜1.5M世代の2つのオブジェクトを確認します。
これには2秒かかります! 名目上のトランザクションは0.1秒未満です。Django Pythonガベージコレクションの問題

私の質問は何ですか?
第2世代スイープをオフにすることができます(非常に高いスレッショルドを設定することで、これは正しいですか?)、GCは従順です。
いつ電源をオンにする必要がありますか?
Djangoを使用してWebサービスを実装し、各ユーザーのリクエストには約0.1秒かかります。
最適なのは、私はこれらのGC gen 2サイクルをユーザAPIリクエストの間に実行します。しかし、どうすればいいのですか?
私のビューは​​で終わり、AFTER gen 2 GCスイープを実行したいです。
どうすればよいですか?このアプローチは理にかなっていますか?

ガベージコレクションで不要なオブジェクトをマークすることができますので、GCは2Ginサイクルごとにテストしませんか?
Djangoサーバが比較的アイドル状態のときにGCをフルスウィープするように設定するにはどうすればよいですか?

複数のプラットフォーム(Windows/Linux)でのPython 2.6.6。

+0

"私のアプリケーションには多くのオブジェクトがメモリに保持されています"どうやって? –

+0

コンテナは標準の辞書です。オブジェクト自体は、自分自身のクラスインスタンス(オブジェクトから派生)またはタプルのいずれかであり、アイテムの1つは前記クラスインスタンスへの参照であり(残りのアイテムはintです)、 –

+0

Django RequestおよびReplyオブジェクトは一時的なものなので、どのようにメモリに何かを保持できますか? –

答えて

3

私は1つのオプションは、ここで提案したようリクエストの終了時に収集し、手動で、その後完全に無効にガベージコレクションになるとと考えている:How does the Garbage Collection mechanism work?

私はあなたがあなたのsettings.pyファイルにGCを無効にすることができることを想像してみてください。

あなたがリクエストごとにGarbageCollectionを実行したい場合は、私がprocess response方法でそれをしない、いくつかのミドルウェアを開発することをお勧め:

import gc 
class GCMiddleware(object): 
    def process_response(self, request, response): 
     gc.collect() 
     return response 
+0

私はこれをまだ実装していませんが、正しいアプローチのように見えます。 –

+1

これは正しいアプローチではありませんが、レスポンスを返す前にGCを収集するので、レスポンスの戻りをブロックします – dalore

0

私の見解は、リターンのHttpResponse(で終わる)、私は希望のその後Gen 2 GCスイープを実行します。

// turn off GC 
// do stuff 
resp = HttpResponse() 
// turn on GC 
return resp 

私はわからないんだけど、代わりにあなたが// spawn thread to turn on GC in 0.1 secすることができるかもしれない//turn on GCの。

要求が処理されるまでGCが実行されないように、スレッドの産出が機能しない場合、dcurtisが示唆するように、django自体を変更するか、djangoフックを使用する必要があります。

パフォーマンスクリティカルなコードを扱っている場合は、その部分にC/C++などの手動メモリ管理言語を使用し、Pythonを使用して呼び出し/照会することもできます。

0

代わりに、GCを完全に無効にし、mod_wsgi(または使用しているもの)を設定してプロセスを強制終了して再起動するように設定することもできます。

1

私たちはgunicornのためにこれをしました。あなたが使用しているwsgiサーバーによっては、レスポンスの後ではなく、正しいフックを見つける必要があります。 Djangoはrequest_finishedシグナルを持っていますが、そのシグナルは依然としてプレレスポンスです。

はgunicornについては、設定であなたはそうのような2つの方法を定義する必要があります。post_requestはここので、HTTP応答が配信された後に実行され、

def pre_request(worker, req): 
    # disable gc until end of request 
    gc.disable() 


def post_request(worker, req, environ, resp): 
    # enable gc after a request 
    gc.enable() 

は、ガベージコレクションのために非常に良い時間です。