Раздувание памяти Python JSON - PullRequest
5 голосов
/ 30 июня 2011
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 top указывает, что процесс python содержит ~ 450 МБ ОЗУ после завершения функции jsontest.Если вызов ' json.loads ' пропущен, то эта проблема не наблюдается.A gc.collect после выполнения этой функции освобождает память .

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

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

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

1 Ответ

3 голосов
/ 30 июня 2011

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

import gc
gc.set_debug(gc.DEBUG_STATS)

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

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

print gc.get_count()

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...