2

大規模なランタイム スクリプトで問題が発生しています。このスクリプトは、クロール タスクを実行するためのマルチスレッド環境です。

大規模な実行では、スクリプトのメモリ消費が膨大になり、guppy hpy でメモリをプロファイリングした後、問題のほとんどが文字列に起因することがわかりました。

私はそれほど多くの文字列を保存していません.htmlのコンテンツをメモリに取得して、dbに保存するだけです. その後、string は使用されなくなります (それを含む変数は次の string に割り当てられます)。

すべての新しい文字列 (sys.getrefcount を使用) に少なくとも 2 つの参照 (var から 1 つ、内部から 1 つ) があることがわかったため、問題が発生しました。var に別の値を再割り当てしても内部参照が削除されないように見えるため、文字列はメモリ内に残ります。

文字列が確実にガベージ コレクションされるようにするにはどうすればよいですか?

前もって感謝します

編集:

1- Django ORM を使用しています

2- 2 つのソースからすべての文字列を取得しています。

2.1- ソケットから直接 (urllib2.urlopen(url).read())

2.2- その応答を解析し、すべての html から新しい URI を抽出し、システムにフィードする

解決した

最後に、鍵を手に入れました。スクリプトは Django 環境の一部であり、Django のアンダーグラウンドでキャッシュなどを行っているようです。デバッグをオフにすると、すべてが期待どおりに機能し始めました (再利用された識別子は古いオブジェクトへの参照を削除するようであり、そのオブジェクトは gc によって収集されます)。

Python である種のフレームワーク レイヤーを使用する場合は、構成に注意してください。集中的なプロセスを伴う一部のデバッグ構成では、メモリ リークが発生する可能性があるようです。

4

2 に答える 2

2

あなたは言う:
すべての新しい文字列(sys.getrefcountを使用)には、少なくとも2つの参照があることがわかりました

しかし、 の説明を注意深く読みましたgetrefcount()か? :

sys.getrefcount()

object) オブジェクトの参照カウントを返します。getrefcount() への引数として (一時的な) 参照が含まれているため、通常、返されるカウントは予想よりも 1 つ多くなります。

.

プログラムについてもっと説明する必要があります。

保持する HTML 文字列のサイズは?
それらはどのように得られますか?すべてのファイルのハンドラ、すべてのソケット接続などを閉じてよろしいですか?

于 2013-03-01T11:37:19.850 に答える
0

文字列への「内部」参照を誰が保持しているかを調べる必要があります。おそらく、DBへの書き込みに使用しているライブラリ(DBへの書き込み方法を指定していません)。objgraphは次のようなタスクに非常に役立ちます:https ://pypi.python.org/pypi/objgraph

例えば

import objgraph
objgraph.show_backrefs([mystring], filename='a.png')
于 2013-03-01T11:14:57.740 に答える