4

运行这个:

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 脚本的框架(上下文?)内导致一些非常糟糕的内存泄漏。

4

1 回答 1

1

在构建 IronPython 引擎时尝试设置“LightweightScopes”。这为我解决了很多垃圾收集问题。

var engineOptions = new Dictionary<string, object> { ["LightweightScopes"] = true };
var scriptEngine = Python.CreateEngine(engineOptions);
于 2017-09-13T16:13:17.883 回答