2011-06-30 2 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 сверху указывает на то, что процесс Python держит ~ 450MB оперативной памяти после завершения «» jsontest функции. Если вызов «json.loads» опущен, этот вопрос не наблюдается. A gc.collect после этого выполнения функции освобождает память.Python JSON памяти раздувание

Похоже, что память не хранится в каких-либо кэшах или в распределителе внутренней памяти python, так как явный вызов gc.collect освобождает память.

Это происходит потому, что порог сбора мусора (700, 10, 10) так и не был достигнут?

Я поставил код после jsontest для имитации порога. Но это не помогло.

ответ

2

Put это в верхней части вашей программы

import gc 
gc.set_debug(gc.DEBUG_STATS) 

и вы получите печатаемый вывод, когда есть коллекция. Вы увидите, что в вашем примере кода нет коллекции после завершения jsontest, пока программа не выйдет.

Вы можете поставить

print gc.get_count() 

, чтобы увидеть текущие отсчеты. Первое число - это избыток распределений по деаллокациям с момента последнего набора генерации 0; вторая (соответственно третья) - это количество времени, в течение которого генерируется 0 (соответственно 1) с момента последней коллекции поколения 1 (соответственно 2). Если вы напечатаете их сразу после завершения jsontest, вы увидите, что подсчеты - (548, 6, 0) или что-то подобное (без сомнения, это зависит от версии Python). Таким образом, порог не был достигнут, и коллекция не состоялась.

Это типичное поведение для планирования сбора мусора на основе пороговых значений. Если вам нужна бесплатная память для своевременного возврата в операционную систему, вам необходимо комбинировать планирование на основе порогового значения с планированием по времени (то есть запросить другую коллекцию по прошествии определенного количества времени с момента последней коллекции , даже если порог не был достигнут).

+0

Даже если мы назовем jsontest несколько раз, память останется на уровне ~ 450 МБ. Это память, используемая при последнем вызове jsontest? Этот код является частью webapp, который обрабатывает сообщения json. Даже после запуска webapp в течение одного часа память, похоже, не будет выпущена. Есть ли обходной путь для этого, кроме gc.collect? – Anoop

+1

Попробуйте напечатать 'gc.get_count()' после каждого вызова 'jsontest', и все должно быть ясно. Кроме того, что случилось с вызовом 'gc.collect'? –

Смежные вопросы