2010-04-20 150 views
3

運行此:IronPython內存泄露?

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

你明確地運行過'gc.collect()'嗎? – doublep 2010-04-20 23:31:31

+0

使用xrange怎麼樣?範圍將創建一個巨大的列表,在循環完成之前不會消失。 – 2010-04-21 00:29:11

+0

CPython的2.6.5做太,它提出: 回溯(最近通話最後一個): 文件 「」,1號線,在 爲我的range(1000000000): 的MemoryError。 xrange的作品,但它對我來說都需要CPython和IronPython的永遠,所以我只是ctrl-C。 – jcao219 2010-04-21 02:04:29

回答

0

嘗試在構建IronPython引擎時設置「LightweightScopes」。這爲我解決了很多垃圾收集問題。

var engineOptions = new Dictionary<string, object> { ["LightweightScopes"] = true }; 
var scriptEngine = Python.CreateEngine(engineOptions);