Почему я пропускаю память с этим циклом Python?

Я пишу пользовательский поисковый робот файловой системы, который заставляет переданные миллионы шариков обрабатывать через sys.stdin. Я нахожу, что при выполнении сценария, его использование памяти увеличивается в широком масштабе со временем, и все это проверяет практически к останову. Я записал минимальный случай ниже который шоу проблема. Я делаю что-то не так, или я нашел ошибку в Python / модуль шарика? (Я использую Python 2.5.2).


#!/usr/bin/env python
import glob
import sys
import gc

previous_num_objects = 0

for count, line in enumerate(sys.stdin):
   glob_result = glob.glob(line.rstrip('\n'))
   current_num_objects = len(gc.get_objects())
   new_objects = current_num_objects - previous_num_objects

   print "(%d) This: %d, New: %d, Garbage: %d, Collection Counts: %s"\
 % (count, current_num_objects, new_objects, len(gc.garbage), gc.get_count())
   previous_num_objects = current_num_objects

Вывод похож:

(0) This: 4042, New: 4042, Python Garbage: 0, Python Collection Counts: (660, 5, 0)
(1) This: 4061, New: 19, Python Garbage: 0, Python Collection Counts: (90, 6, 0)
(2) This: 4064, New: 3, Python Garbage: 0, Python Collection Counts: (127, 6, 0)
(3) This: 4067, New: 3, Python Garbage: 0, Python Collection Counts: (130, 6, 0)
(4) This: 4070, New: 3, Python Garbage: 0, Python Collection Counts: (133, 6, 0)
(5) This: 4073, New: 3, Python Garbage: 0, Python Collection Counts: (136, 6, 0)
(6) This: 4076, New: 3, Python Garbage: 0, Python Collection Counts: (139, 6, 0)
(7) This: 4079, New: 3, Python Garbage: 0, Python Collection Counts: (142, 6, 0)
(8) This: 4082, New: 3, Python Garbage: 0, Python Collection Counts: (145, 6, 0)
(9) This: 4085, New: 3, Python Garbage: 0, Python Collection Counts: (148, 6, 0)

Каждое 100-е повторение, 100 объектов освобождены, таким образом, len(gc.get_objects() увеличения 200 каждыми 100 повторениями. len(gc.garbage) никогда изменения от 0. Количество набора второго поколения увеличивается медленно, в то время как 0th и 1-е количества идут вверх и вниз.

12
задан Andy 2 February 2010 в 12:46
поделиться

2 ответа

Я отследил это до модуля fnmatch. glob.glob вызывает fnmatch для фактического выполнения подстановки, а fnmatch имеет кеш регулярных выражений, который никогда не очищается. Таким образом, при этом использовании кеш постоянно увеличивался и не контролировался. Я зарегистрировал ошибку в библиотеке fnmatch [1].

[1]: http://bugs.python.org/issue7846 Ошибка Python

6
ответ дан 2 December 2019 в 22:51
поделиться

Я не могу воспроизвести какую-либо фактическую утечку в моей системе, но я думаю, что ваша «каждая сотая итерация, 100 объектов освобождаются» - это вы попадаете в кеш для скомпилированных регулярных выражений (через модуль glob). Если вы посмотрите на re.py, вы увидите, что _MAXCACHE по умолчанию равно 100, и по умолчанию весь кеш сдувается, как только вы его нажимаете (в _compile ). Если вы вызовете re.purge () перед вызовом gc , вы, вероятно, увидите, что этот эффект исчезнет.

(обратите внимание, я предлагаю здесь re.purge () только для проверки того, что кеш влияет на ваши результаты gc. Это не обязательно должно быть в вашем фактическом коде.)

I сомневаюсь, что это решает вашу проблему с огромным увеличением памяти.

2
ответ дан 2 December 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: