运行:
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脚本的帧(上下文?)中出现一些非常糟糕的内存泄漏。
答案 0 :(得分:0)
尝试设置" LightweightScopes"当你构建IronPython引擎时。这为我解决了很多垃圾收集问题。
var engineOptions = new Dictionary<string, object> { ["LightweightScopes"] = true };
var scriptEngine = Python.CreateEngine(engineOptions);