2011-06-30 98 views
5
import json 
import time 
from itertools import count 

def keygen(size): 
    for i in count(1): 
     s = str(i) 
     yield '0' * (size - len(s)) + str(s) 

def jsontest(num): 
    keys = keygen(20) 
    kvjson = json.dumps(dict((keys.next(), '0' * 200) for i in range(num))) 
    kvpairs = json.loads(kvjson) 
    del kvpairs # Not required. Just to check if it makes any difference        
    print 'load completed' 

jsontest(500000) 

while 1: 
    time.sleep(1) 

的Linux 頂部表明蟒進程持有〜450MB的 'jsontest' 功能完成之後RAM。如果忽略'json.loads'的呼叫,則不會出現此問題。 A gc.collect此功能執行後確實釋放了內存Python的JSON內存膨脹

由於顯式調用gc.collect釋放內存,所以看起來內存不在任何緩存或python的內部內存分配器中。

發生這種情況是因爲沒有達到垃圾回收閾值(700,10,10)?

我也把一些代碼jsontest後模擬閾值。但它沒有幫助。在你的程序

import gc 
gc.set_debug(gc.DEBUG_STATS) 

頂部

回答

2

把這個,每當有一個集合,你會得到的打印輸出。您將看到在示例代碼中jsontest完成後沒有收集,直到程序退出。

你可以把

print gc.get_count() 

查看當前計數。第一個數字是自第0代最後一次收集以來分配超過釋放的數量;第二個(第三個)是自第一代(第2代)的最後一次收集以來收集的第0代(或第1代)的次數。如果在jsontest完成後立即打印這些文件,則會看到計數爲(548, 6, 0)或類似內容(無疑,這取決於Python版本)。所以沒有達到門檻,也沒有收集。

這是基於閾值的垃圾收集調度的典型行爲。如果您需要及時將可用內存返回到操作系統,則需要將基於閾值的調度與基於時間的調度結合起來(也就是說,在上次收集後經過一段時間後再請求另一個收集,即使沒有達到閾值)。

+0

即使我們多次調用jsontest,內存仍然保持在〜450MB。這是最後jsontest調用使用的內存嗎?這段代碼是處理json消息的webapp的一部分。即使在運行webapp一個小時後,內存似乎也不會被釋放。除了gc.collect之外,還有其他的解決方法嗎? – Anoop

+1

嘗試在每次調用'jsontest'後打印'gc.get_count()',並且全部都應該清楚。另外,調用'gc.collect'有什麼問題? –