我發現exec
(它發生在一個系統中,必須用用戶編寫的腳本來擴展)的問題。我可以在問題本身降低到這個代碼:Python:exec語句和意外的垃圾收集器行爲
def fn():
context = {}
exec '''
class test:
def __init__(self):
self.buf = '1'*1024*1024*200
x = test()''' in context
fn()
我預計,內存應該被垃圾收集器的功能fn
調用之後被釋放。然而,Python進程仍然消耗額外的200MB內存,我完全不知道這裏發生了什麼以及如何手動釋放分配的內存。
我懷疑在exec
中定義一個類並不是一個非常好的想法,但首先,我想了解上述示例中出現的問題。
它看起來像在另一個函數中創建包裝類實例解決了這個問題,但有什麼區別?
def fn():
context = {}
exec '''
class test:
def __init__(self):
self.buf = '1'*1024*1024*200
def f1(): x = test()
f1()
''' in context
fn()
這是我的Python解釋器的版本:
$ python
Python 2.7 (r27:82500, Sep 16 2010, 18:02:00)
[GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2
在你的代碼中做同樣的事情(沒有通過字符串和'exec')給出相同的結果嗎? – delnan 2011-06-09 18:02:07
'gc.collect()'似乎解決了它。某處必須有一個循環循環。瘋狂地猜測,x具有對其類的引用,該類可能具有對其定義的名稱空間的引用,並且該引用又具有對x的引用。 – 2011-06-09 18:04:41
在沒有exec的代碼中,同樣的事情進行得很順利,並且垃圾收集器按預期工作。 – 3xter 2011-06-09 18:07:33