2

私が継承したコードはネストされすぎているため、ここで言い換えることはできません。基本的に、複雑なグラフ構造 (例: graph=NetworkX_graph.copy()) のコピーを作成し、それを名前付きタプルの一部として返すクラス メソッドを定義しています。

返された名前付きタプルは最大値と比較され、それが大きい場合は保持されます。例えば

if value > max_value:
    best_value = {"index": index, "value": value, "graph": graph}

コピーしたオブジェクトに割り当てられたメモリを解放するにはどうすればよいですか?!? 考えられることはすべて試しました。私は現在memory_profilerを使用しており、.copy()を含むメソッドに@profileデコレータをアタッチしています。テストケースのそのコピーは、7.8MB ずつ増分して作業しており (ケースによってはそれより高くなったり低くなったりする可能性があります)、リリースされることはありません。アプリケーション自体が利用可能なシステムメモリを超えてディスクへのスワップを開始するまで、上昇し続けます。(醜い...)

不要になったタプルを None に設定し、「del」に設定してから、gc.collect()、gc.collect(2) を試しました。メモリ使用量は増え続けています。

ところで、私は Python 2.6 で立ち往生しています。強制的に 2.7 に移行することができます。

タプルを使用しているからでしょうか?

4

1 に答える 1

0

わかりました、解決しました。少しリファクタリングが必要でした。オブジェクト参照を (メソッド/関数呼び出しのパラメーターとして) 渡しているときに、その参照を変更すると、新しいメモリが割り当てられます。参照が範囲外になるまで、メモリは解放されません/gc.collect()。たとえば、問題の参照を最初に渡した関数/メソッドにコード ポインタが返され、その関数/メソッドが終了しました。

以下は、問題を説明するために費やすことができるほとんどの時間です。

_compute(self, graph):
    maxValue = 5
    values = {}
    keeper = {}
    values ["graph"] = graph.copy()
    for i in range(1,1000):
        self._process(values )
        if values ["value"] > maxValue:
            keeper = {"graph":values ["graph"], "value":values ["value"]}

_process(self, values):
    graph = values["graph"]
    # Do some graph processing, like make a copy, allocate some memory, add some vertex values, etc... 
    values["value"] = <some value, like 0 to 10>
    values["graph"] = graph

参照として _process に渡された「値」オブジェクトに変更を加えると、変更されたデータの古いバージョンと新しいバージョンを保持する Python ランタイムが発生します。_compute に戻って終了するまで解放されません。

私の修正は、実際にグラフ オブジェクトを返すように _process メソッドを変更することでした。渡された参照を変更する代わりにオブジェクトを返すと、ガベージ コレクションが戻って、割り当てられたメモリが適切に解放されました。

_compute(self, graph):
    maxValue = 5
    values = {}
    keeper = {}
    values ["graph"] = graph.copy()
    for i in range(1,1000):
        newGraph = self._process(values )
        if values ["value"] > maxValue:
            keeper = {"graph":newGraph, "value":values ["value"]}

_process(self, values):
    graph = values["graph"]
    # Do some graph processing, like make a copy, allocate some memory, add some vertex values, etc... 
    values["value"] = <some value, like 0 to 10>
    return graph

私の答えが最善だと言っているわけではありませんし、私は Python の専門家ではないので、何が起こっているのか手がかりさえ持っていると言っているわけではありません。

于 2013-05-03T14:37:35.383 に答える