2009-06-23 170 views
31

我已经创建了一些python代码,它在循环中创建一个对象,并在每次迭代中用相同类型的新代码覆盖此对象。这是10.000次,Python每秒钟占用7MB的内存,直到使用我的3GB RAM。有谁知道从内存中删除对象的方法吗?Python垃圾回收

+0

相关:http://stackoverflow.com/questions/759906/sys-getrefcount-continuation/759970#759970 – codeape 2009-06-23 22:32:07

回答

16

你还没有提供足够的信息 - 这取决于你正在创建的对象的具体细节,以及你在循环中做了什么。如果该对象不创建循环引用,则应在下一次迭代中解除分配。例如,代码

for x in range(100000): 
    obj = " " * 10000000 

不会导致不断增加的内存分配。

+0

我在我的对象中创建循环引用。不能手动删除它吗? – utdiscant 2009-06-23 22:14:38

+8

Python将自动收集带有循环引用的对象*,除非*引用循环中的任何对象都有__del__方法。如果是这样的话,垃圾对象将被移动到gc.garbage列表中,并且您将不得不手动中断参考周期。尽量避免同时使用__del__方法和参考周期。 – Miles 2009-06-23 22:21:28

+5

避免引用循环的一个解决方案是使用weakrefs:http://docs.python.org/library/weakref.html – Miles 2009-06-23 22:27:16

12

这是一个旧的错误,已经在python 2.5中修正了一些类型。发生了什么事情是,python并不擅长收集空列表/字典/ tupes /浮动/整数等内容。在Python 2.5中,这是固定的......主要是。然而,浮点数和整数是用于比较的单例,因此一旦创建了其中一个,只要解释程序还活着,它就会一直保留。在处理大量漂浮物时,我被这种最糟糕的东西咬了,因为他们有一种独特的恶习。这是特点for python 2.4和更新关于它被折叠成python 2.5

我发现它周围的最佳方式是升级到python 2.5或更新,以照顾列表/字典/元组问题。对于数字来说唯一的解决方案是不要让大量的数字进入Python。我已经用我自己的包装器完成了一个C++对象,但我有一个印象numpy.array会给出类似的结果。

作为后脚本,我不知道发生了什么事这在Python 3,但我怀疑数字仍然是一个单独的部分。所以内存泄漏实际上是该语言的一个特征。

+1

尽管如此,这应该不完全是造成问题的原因;即使Python 2.4应该重用释放的内存(它只是没有返回到操作系统)。 – Miles 2009-06-23 22:19:06

1

这里有一两件事你可以在REPL做强制变量的解引用:

>>> x = 5 
>>> x 
5 
>>> del x 
>>> x 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'x' is not defined 
5

如果要创建循环引用,你的对象不会立即释放,但要等待一个GC循环运行。

您可以使用weakref模块来解决这个问题,或者在使用后明确地删除对象。

3

我发现,在我的情况(与Python 2.5.1),与包括有__del__()方法,不仅是垃圾收集不及时发生类循环引用,从来没有得到所谓的我的对象的__del__()方法,即使剧本退出了。所以我用weakref来打破循环引用,一切都很好。

荣誉万里谁在他的评论所提供的所有信息,我把这个在一起。

19

我认为这是循环引用(虽然这个问题不明确这方面的信息。)来解决这个问题

一种方法是手动调用垃圾收集。当您手动运行垃圾收集器时,它也会扫描循环引用的对象。

import gc 

for i in xrange(10000): 
    j = myObj() 
    processObj(j) 
    #assuming count reference is not zero but still 
    #object won't remain usable after the iteration 

    if !(i%100): 
     gc.collect() 

这里不经常运行垃圾回收器,因为它有自己的开销,例如,如果你在每个循环中运行垃圾收集器,解释将变得非常缓慢。