运行这个:
for i in range(1000000000):
a = []
看起来正在创建的列表对象永远不会被标记为垃圾收集。从内存分析器看来,解释器的堆栈帧似乎持有所有列表对象,因此 GC 永远无法对此做任何事情。
这是设计使然吗?
编辑:
这是一个更好的问题示例。使用内存分析器运行以下代码:
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
您将看到在列表推导期间分配的内存永远不会被垃圾收集。这是因为创建的所有对象都被 DLR 中的 InterpreterFrame 对象引用。
现在运行这个:
def get():
return [b for b in range(1000000)]
a = get()
a = get()
a = get()
a = get()
a = get()
a = get()
a = get()
在分析器下,您可以看到这里的内存确实得到了垃圾收集。我猜这是可行的,因为函数的 InterpreterFrame 在函数退出时被清除。
那么,这是一个错误吗?这似乎会在 IronPython 脚本的框架(上下文?)内导致一些非常糟糕的内存泄漏。