Python2.6GC似乎可以清理对象,但不会释放内存
我有一个用python 2.6编写的程序,它创建了大量短期实例(这是一个典型的生产者-消费者问题)。我注意到top和pmap报告的内存使用率在创建这些实例时似乎会增加,而且不会下降。我担心我正在使用的一些python模块可能会泄漏内存,所以我在代码中仔细地隔离了这个问题。然后,我继续用尽可能简短的例子重现它。我想到了这个:Python2.6GC似乎可以清理对象,但不会释放内存,python,memory,memory-leaks,Python,Memory,Memory Leaks,我有一个用python 2.6编写的程序,它创建了大量短期实例(这是一个典型的生产者-消费者问题)。我注意到top和pmap报告的内存使用率在创建这些实例时似乎会增加,而且不会下降。我担心我正在使用的一些python模块可能会泄漏内存,所以我在代码中仔细地隔离了这个问题。然后,我继续用尽可能简短的例子重现它。我想到了这个: class LeaksMemory(list): timesDelCalled = 0 def __del__(self): LeaksMe
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 memoryleak.py”的东西运行它,它将停止,您可以使用pmap-x PID检查内存使用情况。我添加了del方法,以便验证GC是否正在发生。它在我的实际程序中不存在,并且似乎没有任何功能上的区别。每次调用leakSomeMemory()都会增加此程序消耗的内存量。我担心我犯了一些简单的错误,引用被意外保留,但无法识别。Python将释放对象,但不会立即将内存释放回操作系统。相反,它将在同一解释器中重新使用相同的段,以便将来进行分配 以下是一篇关于这个问题的博客: 更新:我自己用Python2.6.4进行了测试,没有注意到内存使用量的持续增加。对
leakSomeMemory()
的一些调用导致Python进程的内存占用增加,一些调用使其再次减少。因此,这完全取决于分配器如何重新使用内存。根据:
“唯一真正可靠的方法
确保大型但临时使用
内存的使用会将所有资源返回到
系统完成后,将
这种使用发生在子流程中,而
那么,需要记忆的东西还能用吗
终止。”
因此,在您的情况下,使用模块在单独的流程中运行短期函数以确保流程完成时返回资源似乎是有意义的
import multiprocessing as mp
def NOT_leakSomeMemory():
# do stuff
return result
if __name__=='__main__':
pool = mp.Pool()
results=pool.map(NOT_leakSomeMemory, range(500000))
有关如何使用多处理进行设置的更多信息,请参阅:如果您稍等片刻,内存消耗是否会下降?我的理解是Python是在池外进行分配的,因此如果它必须增加池,它可能不会在将内存释放回池中后立即收缩池。