我无法显示更多代码,但请参阅此示例:
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包,我得到了引用的图形,并且泄漏对象的引用路径转到该回溯对象,然后什么也没有。如果没有抛出异常,则释放内存。
这是图表:
对于大图片,我很抱歉。左边的堆栈是我玩调试器,不要介意他们。我突出了泄漏。