Python 垃圾回收

43 投票
7 回答
57631 浏览
提问于 2025-04-15 12:27

我写了一段Python代码,这段代码在一个循环里创建了一个对象,每次循环都会用一个新的同类型对象覆盖掉之前的那个。这个过程重复了10,000次,结果是Python每秒钟占用7MB的内存,直到我的3GB内存用完为止。有没有人知道怎么把这些对象从内存中清除掉呢?

7 个回答

13

这是一个老问题,在Python 2.5版本中对某些类型进行了修复。之前的问题是,Python在处理像空列表、字典、元组、浮点数和整数这些东西时表现得不太好。在Python 2.5中,这个问题大部分得到了修复。不过,浮点数和整数在比较时是单例,也就是说一旦创建了一个,它就会一直存在,直到解释器关闭。我在处理大量浮点数时遇到过这个问题,因为它们有个讨厌的习惯,就是每个都是独一无二的。这个问题在Python 2.4中有详细描述,并在Python 2.5中进行了更新。

我发现解决这个问题的最好办法是升级到Python 2.5或更新的版本,这样可以解决列表、字典和元组的问题。至于数字,唯一的解决办法就是不要让大量数字进入Python。我自己用C++对象做了一个封装,感觉numpy.array也能得到类似的效果。

最后,我对Python 3中的情况不太清楚,但我怀疑数字仍然是单例的一部分。所以,内存泄漏实际上可能是这个语言的一个特性。

33

我觉得这可能是个循环引用的问题(虽然问题没有明确提到这一点)。

解决这个问题的一种方法是手动调用垃圾回收。手动运行垃圾回收时,它会清理那些有循环引用的对象。

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()

不过,不要太频繁地运行垃圾回收,因为它本身也会消耗资源,比如如果你在每次循环中都运行垃圾回收,程序的运行速度会变得非常慢。

22

你没有提供足够的信息——这取决于你正在创建的对象的具体情况,以及你在循环中对它的其他操作。如果这个对象没有形成循环引用,它应该会在下一次循环时被释放掉。比如,下面的代码

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

不会导致内存不断增加。

撰写回答