7

История:Просмотр списков поколения во время выполнения программы

Во Nina Zakharenko's PyCon talk по управлению памятью в Python, она объясняет, как в поколений сбора мусора работает в Python, отметив, что:

Python ведет список каждого объекта, созданного при запуске программы. На самом деле, это делает 3:

  • generation 0
  • generation 1
  • generation 2

Вопрос:

Чтобы получить более глубокое понимание в области управления памятью в Python и для цель отладки утечек памяти, Как я могу наблюдать/наблюдать, какие объекты добавляются и удаляются из всех списков 3 поколений во время прогона программы?

Я просмотрел gc module, но не нашел соответствующего метода для получения значений текущего поколения.

+0

Вы имеете в виду установку 'gc.set_debug (flags ...)'? –

+0

@PadraicCunningham в этот момент, я не знаю, что я имею в виду, так как это очень ново для меня. Я не пробовал устанавливать режим отладки. Позвольте мне посмотреть, помогает ли это просматривать списки генерации. Благодаря! – alecxe

+0

@PadraicCunningham 'gc.set_debug()' отладочный вывод выглядит связанным, но он по-прежнему не предоставляет список объектов в списках генерации.в основном, в идеале, я хотел бы видеть, какие объекты находятся внутри списков и как списки изменяются во время выполнения программы. – alecxe

ответ

3

Как мы обсуждали в комментариях, я не думаю, что есть способ получить доступ к спискам генерации непосредственно из python, вы можете установить некоторые флаги отладки, в python2 вы можете использовать следующее для сообщения объектов, которые могут или не могут сбор:

import gc 

gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_COLLECTABLE | gc.DEBUG_OBJECTS) 

В Python3, используя следующие даст вам некоторый вывод поколения и информацию о коллекционных и безнадежных объектов:

import gc 

gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_COLLECTABLE | gc.DEBUG_STATS) 

Вы получаете выход как:

gc: collecting generation 2... 
gc: objects in each generation: 265 4454 0 
gc: collectable <function 0x7fad67f77b70> 
gc: collectable <tuple 0x7fad67f6f710> 
gc: collectable <dict 0x7fad67f0e3c8> 
gc: collectable <type 0x285db78> 
gc: collectable <getset_descriptor 0x7fad67f095e8> 
gc: collectable <getset_descriptor 0x7fad67f09630> 
gc: collectable <tuple 0x7fad67f05b88> 
gc: done, 7 unreachable, 0 uncollectable, 0.0028s elapsed. 
gc: collecting generation 2... 

Для утечек согласно gc.DEBUG_SAVEALL, когда установлено, все недостижимые объекты будут добавлены к мусору, а не освобождены. Это может быть полезно для отладки протекающих программ:

import gc 

gc.set_debug(gc.DEBUG_SAVEALL) 

В Python3, вы можете также добавляемые обратный вызов, которая выполняется, когда ГЦ начинаются и заканчивается, простой пример:

def f(phase, info): 
    if phase == "start": 
     print("starting garbage collection....") 
    else: 
     print("Finished garbage collection.... \n{}".format("".join(["{}: {}\n".format(*tup) for tup in info.items()]))) 

     print("Unreachable objects: \n{}".format(
      "\n".join([str(garb) for garb in gc.garbage]))) 
     print() 


gc.callbacks.append(f) 

Объединение gc.DEBUG_SAVEALL при этом функция покажет вам любые недоступные объекты, не сильно отличающиеся от установки DEBUG_COLLECTABLE или DEBUG_LEAK, но один пример добавления callback.

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