什么可以防止追溯被垃圾收集?

时间:2017-06-21 16:35:36

标签: python python-3.x memory-leaks clr

我无法显示更多代码,但请参阅此示例:

class Product(metaclass=abc.ABCMeta):
    __attributes__ = []
    __special_attributes__ = []
    __json_additional_attributes__ = []

    def __init__(self, original_object):
        for attribute in [c_attr for c_attr in self.__attributes__
                            if c_attr not in self.__special_attributes__]:
            try:
                if hasattr(original_object, attribute):
                    # ...
                elif original_object.IsAttributeUsed(attribute):
                    # RAISES HERE - this is a clr binding
                    # ...
            except Exception as err:
                print('cant retrieve attr ' + attribute)

    # ...

我删除了简洁的线条。这里,original_object是从clr绑定获得的对象。有时original_object.IsAttributeUsed(attribute)会在DLL端引发异常。异常在except块中按预期捕获。

问题是:由于某种原因,它会泄漏内存,因为来自此异常的回溯对象永远不会被收集。回溯保持对堆栈中的整个帧的引用,其反过来引用所有本地。这是一个批处理,因此这个堆栈可以容纳8Gb的内存,因此我很快就会运行内存。

由于objgraph包,我得到了引用的图形,并且泄漏对象的引用路径转到该回溯对象,然后什么也没有。如果没有抛出异常,则释放内存。

这是图表:

objgraph

对于大图片,我很抱歉。左边的堆栈是我玩调试器,不要介意他们。我突出了泄漏。

0 个答案:

没有答案