2013-12-10 151 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()) 

釋放所有訪問的內存,並在不忙時保持正確的資源進程。奇怪,但是是真的。