22. 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)
piątek, 27 września 13
23. 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)
piątek, 27 września 13
At start
: 2
Second reference : 3
After del
: 2
24. Анализ графа объектов
• Функции для анализа в модуле gc
• gc.get_referrers(*objs)
• gc.get_referents(*objs)
• Native-объекты должны предоставлять метод
tp_traverse
piątek, 27 września 13
25. Модуль weakref
• Слабые ссылки с callback на удаление объекта
• Proxy-объекты бросающие исключение при
использовании удаленного объекта (not hashable!)
• WeakValue и WeakKey словари
• WeakSet (3.2)
piątek, 27 września 13
26. 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
piątek, 27 września 13
27. Ограничения
• Не все типы могут быть weak: string, list,
tuple...
• Native-объекты должны реализовывать
поддержку (через tp_weaklistoffset )
• Осторожно с weak словарями!
piątek, 27 września 13
28. Garbage Collector
• Удаляет объекты,
недостижимые по
ссылкам из
корневого объекта
но с ненулевым
счетчиком ссылок
piątek, 27 września 13
29. GC в python
• Запускается когда колличество созданых
объектов поколения превышает количество
удаленных на х (по умолчанию 700, 10, 10)
• Либо вручную gc.collect()
• Low memory, idle не инициируют сборку
мусора
• Может работать долго
piątek, 27 września 13
32. Generations and thresholds
• 3 "поколения" (списка) объектов: 0, 1,
• Новые объекты попадают в 0 (не все)
piątek, 27 września 13
2
33. Generations and thresholds
• 3 "поколения" (списка) объектов: 0, 1,
• Новые объекты попадают в 0 (не все)
• Сборка мусора работает по поколениям
piątek, 27 września 13
2
34. Generations and thresholds
• 3 "поколения" (списка) объектов: 0, 1,
• Новые объекты попадают в 0 (не все)
• Сборка мусора работает по поколениям
• Объекты пережившие сборку мусора
переносятся в поколение +1
piątek, 27 września 13
2
35. Generations and thresholds
• 3 "поколения" (списка) объектов: 0, 1,
• Новые объекты попадают в 0 (не все)
• Сборка мусора работает по поколениям
• Объекты пережившие сборку мусора
2
переносятся в поколение +1
• Поколение 1 проверяется после threshold1
обработок поколения 0
piątek, 27 września 13
36. Ограничения GC
• Объекты с определенным __del__ не
уничтожаются GC (он не знает в каком
порядке их вызвать)
• Native-объекты которые могут содержать
ссылки должны правильно реализовывать
tp_traverse
piątek, 27 września 13
37. Проблемы с __del__
• Может создать циклические ссылки с
sys.exc_traceback и
sys.last_traceback (их нужно явно
занулить)
• Исключения в __del__ игнорируются с
выводом сообщения на stderr
• Не вызывается при завершении программы
piątek, 27 września 13
38. Удаление неудаляемых
объектов
• Вызвать gc.collect() что бы явно
запустить сборку мусора (вернет количество
удаленных объектов
• В gc.garbage список объектов с
циклическими ссылками и __del__.
Проходим по этому списку и разрываем
циклические ссылки. (gc.get_referrers)
• del
piątek, 27 września 13
gc.garbage[:]
40. Альтернативы
• PyPy
• Отключить GC вообще и следить за деревом
объектов вручную
• Отключить но вызывать gc.collect() в
правильные моменты времени
piątek, 27 września 13