Python: регистрация сборщика мусора - PullRequest
2 голосов
/ 18 ноября 2011

У меня есть приложение на Python, которое имеет некоторые проблемы с производительностью.Я хочу добавить события сборщика мусора (особенно, когда он вызывается) в мои журналы.Является ли это возможным?

спасибо.

Ответы [ 2 ]

5 голосов
/ 18 ноября 2011

http://docs.python.org/library/gc.html#gc.set_debug

Вы можете установить флаги, но они записываются в stderr.

Доступные флаги:

gc.DEBUG_STATS
gc.DEBUG_COLLECTABLE
gc.DEBUG_UNCOLLECTABLE
gc.DEBUG_INSTANCES
gc.DEBUG_OBJECTS
gc.DEBUG_SAVEALL
gc.DEBUG_LEAK

1010 * ТАКЖЕ *

Когда вы имеете дело с производительностью, вы можете профилировать свой код для исчерпывающих циклов или вызовов функций. Вы можете использовать cProfile или hotshot. Подробнее здесь http://docs.python.org/library/profile.html

1 голос
/ 18 ноября 2011

Python (по крайней мере, CPython версии 2.x) использует подсчет ссылок для реализации своего сборщика мусора (см. Почему методы сбора мусора в Java и Python различаются? ), поэтому он не «вызывается», как это в Java.

Refcounting означает, что каждый раз, когда создается новая ссылка на данный объект, счетчик увеличивается, каждый раз, когда ссылка теряется (конец области действия, переназначение, ...), счетчик уменьшается. Когда он достигает 0, память объекта освобождается.

Таким образом, решение, которое Python предлагает вашей проблеме, заключается в переопределении метода __del__ объекта:

class test:
    def __del__(self):
         #self is about to be freed, do what ever you want 
         pass

EDIT: По ссылке выше, периодически запускается еще один механизм:

CPython (подсчет ссылок не является частью самого Python, но является частью его реализации на C) ловит циклические ссылки с помощью отдельной процедуры сборки мусора, которую он периодически запускает ...

но применяется только в случае циклических ссылок.

РЕДАКТИРОВАТЬ 2: Как уже упоминалось в комментариях и здесь , __del__ не самое безопасное решение. Вот, безусловно, лучший способ добиться подобного поведения:

import weakref

class test:
    pass

t = test()

def prepare_cb(obj):
  #save information about the obj
  uid = id(obj)

  def do_some_logging(weak):
     print "Object %s cleaned up" % uid

  return do_some_logging

weak = weakref.ref(t, prepare_cb(t))

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