2013-04-29 23 views
10

私はそれぞれ0.5GBのピクルファイルを50個持っています。 各ピクルファイルは、カスタムクラスオブジェクトのリストで構成されています。私は繰り返し、私はメモリリークを取得したファイル をロードしようとすると、しかしforループで大規模なpickleファイルを読み込むと、メモリリークを防ぐ方法を教えてください。

def loadPickle(fp): 
    with open(fp, 'rb') as fh: 
     listOfObj = pickle.load(fh) 
    return listOfObj 

: は、私は何の問題 次の関数を使用して、個別にファイルをロードしていません。

l = ['filepath1', 'filepath2', 'filepath3', 'filepath4'] 
for fp in l: 
    x = loadPickle(fp) 
    print('loaded {0}'.format(fp)) 

loaded filepath2が印刷される前にメモリがオーバーフローしました。 各反復中にピクルが1つだけロードされることを保証するコードを作成するにはどうすればよいですか?

weakrefモジュールで定義されたオブジェクトや、gcモジュールを使用した明示的なガベージコレクションを使用することを推奨しますが、これらのメソッドを特定のユースケースにどのように適用するのかを理解するのは困難です。これは、私がフードの中でどのように参照が機能するかについての理解が不十分なためです。

関連:Python garbage collection

+0

'の後ろに' x = None'をつけてみましょう。 –

+0

こんにちはIonut Hulub、ありがとう。出来た! –

+2

実際のメモリリークはありません。新しい値が割り当てられるまで古い 'x'値を解放することはできないので、一度に2つの値をメモリに格納するだけのメモリが必要です。 – abarnert

答えて

7

あなたはfor fp in l:x = None権利を追加することによって、これを修正することができます。

変数xを逆参照し、2回目にloadPickle()を呼び出す前にpythonガベージコレクタが仮想メモリを解放できるようにするためです。

+1

これは実際に動作することは保証されていません。参照を停止すると、Pythonはオブジェクトを破棄することができますが、_required_ toではありません。幸運なことに、CPythonの実装_will_はそうしています。循環参照がどこにもない限り、明示的に文書化されていないものに依存するコードは、少なくともコメントと警告が必要です。 – abarnert

+0

それは本当です。 @abarnertの追加をありがとう –

+7

'del x'をする方が良いのではないでしょうか?変数 'x'が逆参照されるようにしてください。 – juliomalegria

関連する問題