1

ファイル (hfd5 - pytables) をオブジェクト構造にロードするライブラリに取り組んでいます。構造体に使用されている実際のクラスは、hdf5 ファイルから文字列として読み込まれ、次の方法で読み込まれます。

class NamespaceHolder(dict):
    # stmt is the source code holding all the class defs
    def execute(self, stmt):
        exec stmt in self

問題は、このように複数のクラスをロードすると、ガベージ コレクションの収集不可能な部分、つまり実際のクラス定義にオブジェクトが表示されることです。これをグローバル ディクショナリに読み込むこともできますが、問題は孤立したクラスのままです。クラスをアンロードする方法はありますか?

主な問題はクラスです。mro属性には、クラス自体への参照が含まれているため、ガベージ コレクターが処理できない循環参照が発生します。

以下は、自分で確認するための小さなテスト ケースです。

import gc

if __name__ == "__main__":
    gc.enable()
    gc.set_debug(gc.DEBUG_LEAK)

    code = """
class DummyA(object):
    pass
"""
    context = {}

    exec code in context
    exec code in context

    gc.collect()
    print len(gc.garbage)

注意: 以前にクラスを作成するためにファイル内のテキストの解析を使用することに反対したことはすでにありますが、どうやら彼らはここでそれを使用することに設定されており、私が知らないいくつかの利点があるため、このソリューションから離れることは今のところ現実的ではありません.

4

2 に答える 2

1

gc.set_debug(gc.DEBUG_LEAK) がリークを引き起こします。これを試して:

import gc

def foo():                              
    code = """
class DummyA(object):
    pass             
"""
    context = {}
    exec code in context
    exec code in context

    gc.collect()
    print len(gc.garbage), len(gc.get_objects())

gc.enable()
foo(); foo() # amount of objects doesn't increase
gc.set_debug(gc.DEBUG_LEAK)
foo() # leaks
于 2009-05-28T12:07:44.750 に答える
1

GC は循環参照に対処できると思いますが、globals() dict から参照を削除する必要があります。

try:
    del globals()['DummyA']
except KeyError:
    pass

そうしないと、クラス オブジェクトへの非循環参照が発生し、クリーンアップが停止します。

于 2009-05-28T09:37:32.400 に答える