8
import os
import xml.etree.ElementTree as et

for ev, el in et.iterparse(os.sys.stdin):
    el.clear()

上記をODP構造のRDFダンプで実行すると、常にメモリが増加します。何故ですか?clear()子ノードがedであっても、ElementTreeはまだ解析ツリーを構築していることを理解しています。それがこのメモリ使用パターンの原因である場合、それを回避する方法はありますか?

4

3 に答える 3

10

clear各要素を使用していますが、それらへの参照はルートドキュメントに残ります。したがって、個々の要素をガベージコレクションすることはできません。

解決策は、次のようにルート内の参照をクリアすることです。

import xml.etree.ElementTree as ET

# get iterator
context = ET.iterparse(source, events=("start", "end"))

# get the root element
event, root = next(context)

for event, elem in context:
    if event == "end" and elem.tag == "record":
        # process record elements here...
        root.clear()

状況に影響を与えない可能性があるメモリ使用量について覚えておくべきもう1つのことは、VMがシステムからヒープストレージにメモリを割り当てると、通常、そのメモリが返されることはないということです。ほとんどのJavaVMもこのように機能します。したがって、ヒープメモリが使用されていない場合でも、インタプリタのサイズが減少するtopことは期待できません。ps

アップデート :

Python3以降で動作するようにコードが変更されました。

于 2012-04-09T19:26:35.503 に答える
0

私は同じ問題に遭遇しました。ドキュメントは物事をあまり明確にしません。私の場合の問題は次のとおりです。

1) clear を呼び出すと、子ノードのメモリが解放されます。ドキュメントによると、すべてのメモリが解放されます。Clear は、clear が呼び出されたメモリを解放しません。そのメモリは、それを割り当てた親に属しているためです。2) root.clear() を呼び出します。これは、ルートが何であるかによって異なります。ルートが親である場合、それは機能します。そうしないと、メモリが解放されません。

修正は、親への参照を保持することでした。ノードが不要になったら、parent.remove(child_node) を呼び出します。これは機能し、メモリ プロファイルを数 KB に維持しました。

于 2016-03-21T22:52:31.127 に答える