Python 垃圾回收
我写了一段Python代码,这段代码在一个循环里创建了一个对象,每次循环都会用一个新的同类型对象覆盖掉之前的那个。这个过程重复了10,000次,结果是Python每秒钟占用7MB的内存,直到我的3GB内存用完为止。有没有人知道怎么把这些对象从内存中清除掉呢?
7 个回答
这是一个老问题,在Python 2.5版本中对某些类型进行了修复。之前的问题是,Python在处理像空列表、字典、元组、浮点数和整数这些东西时表现得不太好。在Python 2.5中,这个问题大部分得到了修复。不过,浮点数和整数在比较时是单例,也就是说一旦创建了一个,它就会一直存在,直到解释器关闭。我在处理大量浮点数时遇到过这个问题,因为它们有个讨厌的习惯,就是每个都是独一无二的。这个问题在Python 2.4中有详细描述,并在Python 2.5中进行了更新。
我发现解决这个问题的最好办法是升级到Python 2.5或更新的版本,这样可以解决列表、字典和元组的问题。至于数字,唯一的解决办法就是不要让大量数字进入Python。我自己用C++对象做了一个封装,感觉numpy.array也能得到类似的效果。
最后,我对Python 3中的情况不太清楚,但我怀疑数字仍然是单例的一部分。所以,内存泄漏实际上可能是这个语言的一个特性。
我觉得这可能是个循环引用的问题(虽然问题没有明确提到这一点)。
解决这个问题的一种方法是手动调用垃圾回收。手动运行垃圾回收时,它会清理那些有循环引用的对象。
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()
不过,不要太频繁地运行垃圾回收,因为它本身也会消耗资源,比如如果你在每次循环中都运行垃圾回收,程序的运行速度会变得非常慢。
你没有提供足够的信息——这取决于你正在创建的对象的具体情况,以及你在循环中对它的其他操作。如果这个对象没有形成循环引用,它应该会在下一次循环时被释放掉。比如,下面的代码
for x in range(100000):
obj = " " * 10000000
不会导致内存不断增加。