2013-12-10 90 views
3

我一直在使用XML资源,似乎Python发出奇怪的行为。我已经测试了lxml库和xml.etree.ElementTree,两者都应该由gc收集后保存内存。我输入gc.collect()作为测试,但没有其他事情发生:内存仍然按进程持有。Python不释放内存

进口:

import time 
from lxml import etree 
import gc 

这是代码:

def process_alternative(): 
    """ 
    This alternative process will use lxml 
    """ 
    filename = u"/tmp/randomness.xml" 
    fd = open(filename, 'r') 
    tree = etree.parse(fd) 
    root = tree.getroot() 

    accum = {} 

    for _item in root.iter("*"): 
     for _field in _item.iter("*"): 
      if _field.tag in accum.keys(): 
       accum[_field.tag] += 1 
      else: 
       accum[_field.tag] = 1 

    for key in accum.keys(): 
     print "%s -> %i" % (key, accum[key]) 

    fd.close() 
    gc.collect() 

这是我的主要

if __name__ == "__main__": 
    while True: 
     print "Wake up!" 
     process_alternative() 
     print "Sleeping..." 
     time.sleep(30) 

正如你看到的,这主要电话 “process_alternative”,然后睡觉。提供的XML文件加载了将近800Mb的内存;因此,在time.sleep之前,应该通过进程释放内存,返回所需的基本VM内存(大约32Mb?)。相反,过程继续保持在800Mb左右。

为什么内存没有被每次迭代后释放任何提示?

使用Ubuntu 13.04,Python的2.7.4

这个函数释放内存在每次迭代

def check_memory(): 
    ac1 = [a1**5 for a1 in xrange(10000000)] 
    time.sleep(5) 
    ac2 = [a1**5 for a1 in xrange(10000000)] 
    time.sleep(5) 
    ac3 = [a1**5 for a1 in xrange(10000000)] 
+3

这是我的理解是蟒蛇从来没有真正指定*时*甚至*如果*内存被返回到操作系统 - 只有当Python对象“释放”(意思是它们占用的内存可以被重新用于由新对象)。 – mgilson

+1

如果您将'gc.collect()'移到'process_alternative'函数之外并进入'while True',会发生什么情况,所以当您运行收集器时,您仍然不会保留对巨型数据结构的引用? – user2357112

+0

似乎调用gc.collect()的位置并不重要。我把它放在一边睡觉,资源仍然是按程序保存的。 Top显示我的进程不占用cpu(0%),但仍然占用内存(21%,RES中约为800Mb) – Isaac

回答

-1

我不知道为什么,但过程仍持有的内存,甚至当我设置的显式调用GC.Collect的()。

一些上场后,并感谢的Martijn Pieters的,一个解决方案出现。调用

len(gc.get_objects()) 

释放所有访问的内存,并在不忙时保持正确的资源进程。奇怪,但是是真的。