Python2.6GC看起来像是在清理对象,但并没有释放内存

2024-06-14 01:53:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个用Python2.6编写的程序,可以创建大量的短生命实例(这是一个典型的生产者-消费者问题)。我注意到top和pmap报告的内存使用量在创建这些实例时似乎会增加,而且永远不会下降。我担心我使用的某些python模块可能会泄漏内存,所以我在代码中仔细地隔离了这个问题。然后我继续用尽可能短的例子来重现它。我想到了这个:

class LeaksMemory(list):
    timesDelCalled = 0

    def __del__(self):
        LeaksMemory.timesDelCalled +=1


def leakSomeMemory():
    l = []
    for i in range(0,500000):
        ml = LeaksMemory()
        ml.append(float(i))
        ml.append(float(i*2))
        ml.append(float(i*3))
        l.append(ml)

import gc
import os


leakSomeMemory()

print("__del__ was called " + str(LeaksMemory.timesDelCalled) + " times")
print(str(gc.collect())  +" objects collected")
print("__del__ was called " + str(LeaksMemory.timesDelCalled) + " times")
print(str(os.getpid()) + " : check memory usage with pmap or top")

如果你用“python2.6-i”之类的东西来运行这个内存leak.py'它将停止,您可以使用pmap-xpid检查内存使用情况。我添加了del方法,这样我就可以验证GC是否发生了。它在我的实际程序中并不存在,似乎没有任何功能上的区别。每次调用leakSomeMemory()都会增加该程序消耗的内存量。我担心我犯了一些简单的错误,参考文献是偶然被保留的,但无法识别。在


Tags: 实例内存程序topdeffloatmlprint
2条回答

Python将释放对象,但不会立即将内存释放回操作系统。相反,它将在同一个解释器中为将来的分配重用相同的段。在

这里有一篇关于这个问题的博文:http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

更新:我自己用python2.6.4测试了这一点,但没有注意到内存使用量的持续增加。对leakSomeMemory()的一些调用导致Python进程的内存占用增加,而另一些则使其再次减少。所以这完全取决于分配器如何重新使用内存。在

根据Alex Martelli

"The only really reliable way to ensure that a large but temporary use of memory DOES return all resources to the system when it's done, is to have that use happen in a subprocess, which does the memory-hungry work then terminates."

因此,在您的情况下,使用multiprocessing模块在单独的进程中运行短期函数,以确保进程完成时资源的返回是有意义的。在

import multiprocessing as mp

def NOT_leakSomeMemory():
    # do stuff
    return result


if __name__=='__main__':
    pool = mp.Pool()
    results=pool.map(NOT_leakSomeMemory, range(500000)) 

有关如何使用多处理进行设置的更多信息,请参见Doug Hellman's tutorial

相关问题 更多 >