Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Garbage collector and a bit of memory management in Python

Cyril Lashkevich
March 13, 2014
48

Garbage collector and a bit of memory management in Python

Cyril Lashkevich

March 13, 2014
Tweet

Transcript

  1. Что делать если циклы нужны? • Пример: граф с циклами

    • Приходится устранять циклы вручную
  2. Python sys.getrefcount() import sys! ! one = []! print 'At

    start :', sys.getrefcount(one)! two = one! print 'Second reference :', sys.getrefcount(one)! del two! print 'After del :', sys.getrefcount(one) At start : 2! Second reference : 3! After del : 2
  3. Анализ графа объектов • Функции для анализа в модуле gc

    • gc.get_referrers(*objs)! • gc.get_referents(*objs)! • Native-объекты должны предоставлять метод tp_traverse
  4. Модуль weakref • Слабые ссылки с callback на удаление объекта

    • Proxy-объекты бросающие исключение при использовании удаленного объекта (not hashable!) • WeakValue и WeakKey словари • WeakSet (3.2)
  5. In [11]: obj = ExpensiveObject() In [12]: r = weakref.ref(obj)

    In [15]: print('obj:', obj) obj: <__main__.ExpensiveObject object at 0x108ea24d0> In [16]: print('ref:', r) ref: <weakref at 0x108eb62b8; to 'ExpensiveObject' at 0x108ea24d0> In [17]: print('r():', r()) r(): <__main__.ExpensiveObject object at 0x108ea24d0> In [18]: del obj Deleting Expencive object In [19]: print('r():', r()) r(): None
  6. Ограничения • Не все типы могут быть weak: string, list,

    tuple... • Native-объекты должны реализовывать поддержку (через tp_weaklistoffset ) • Осторожно с weak словарями!
  7. GC в python • Запускается когда колличество созданых объектов поколения

    превышает количество удаленных на х (по умолчанию 700, 10, 10) • Либо вручную gc.collect()! • Low memory, idle не инициируют сборку мусора • Может работать долго
  8. Generations and thresholds • 3 "поколения" (списка) объектов: 0, 1,

    2 • Новые объекты попадают в 0 (не все) • Сборка мусора работает по поколениям • Объекты пережившие сборку мусора переносятся в поколение +1 • Поколение 1 проверяется после threshold1 обработок поколения 0
  9. Ограничения GC • Объекты с определенным __del__ не уничтожаются GC

    (он не знает в каком порядке их вызвать) • Native-объекты которые могут содержать ссылки должны правильно реализовывать tp_traverse
  10. Проблемы с __del__ • Может создать циклические ссылки с sys.exc_traceback

    и sys.last_traceback (их нужно явно занулить) • Исключения в __del__ игнорируются с выводом сообщения на stderr • Не вызывается при завершении программы
  11. Удаление неудаляемых объектов • Вызвать gc.collect() что бы явно запустить

    сборку мусора (вернет количество удаленных объектов • В gc.garbage список объектов с циклическими ссылками и __del__. Проходим по этому списку и разрываем циклические ссылки. (gc.get_referrers) • del gc.garbage[:]
  12. Альтернативы • PyPy • Отключить GC вообще и следить за

    деревом объектов вручную • Отключить но вызывать gc.collect() в правильные моменты времени