【发布时间】:2010-04-20 23:28:50
【问题描述】:
运行这个:
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 脚本的框架(上下文?)内导致一些非常糟糕的内存泄漏。
【问题讨论】:
-
你是否明确运行
gc.collect()? -
使用 xrange 怎么样? range 将创建一个巨大的列表,在循环完成之前不会消失。
-
CPython 2.6.5 也这样做,它引发: Traceback(最近一次调用最后一次):文件“
”,第 1 行,在 中 for i in range(1000000000) : 内存错误。 xrange 有效,但对我来说 CPython 和 IronPython 都需要很长时间,所以我只需 ctrl-C。 -
问题不在范围函数中...查看我的编辑
标签: ironpython dynamic-language-runtime