Skip to content

Instantly share code, notes, and snippets.

@Lurunchik
Created March 19, 2015 08:11
Show Gist options
  • Save Lurunchik/a6b3abf244cbe991bb17 to your computer and use it in GitHub Desktop.
Save Lurunchik/a6b3abf244cbe991bb17 to your computer and use it in GitHub Desktop.
если в крации про object.__del__(self)
del x не является прямым вызовом x.__del__() - первая форма сокращает количество ссылок на объект x на одну, тогда как последний метод вызывается только когда количество ссылок достигает нуля. В некоторых часто встречающихся случаях могут возникнуть ситуации, мешающие обнулению счётчика, как то:
взаимные ссылки между объектами (в списках или в деревьях)
ссылки на объекты в стеке функции, где было вызвано исключение, так как в таком случае ссылки на объекты этого стека сохранены в sys.exc_traceback
ссылки на объекты в стеке, если было вызвано не перехваченное исключение в интерактивном режиме (так как в таком случае ссылки на объекты сохранены в sys.last_traceback)
Валерия Болотова: все на оф написано только на ангийском
[12:56:27] Валерия Болотова: В первом случае необходимо явно разрушить циклические ссылки; во втором и третьем - сохранить None в sys.exc_traceback или sys.last_traceback. Циклические ссылки определяются сборщиком мусора, если активирована соответствующая опция (как оно и есть по умолчанию), однако, если вызывается метод del() в коде, такие ссылки не будут обработаны автоматически.
[13:05:00] Валерия Болотова: Пример Кирилла
class Topic(object):
def __init__(self, comments):
"""
:param list of Comment comments: list
"""
self.my_connetns = comments
for c in comments:
c.my_topic = self
class Comment(object):
def __init__(self, text):
self.my_topic = None
self.text = text
t = Topic([Comment('1'), Comment('4')])
print(call)
[13:05:10] Валерия Болотова: сделай точку остановы на принте
[13:05:19] Валерия Болотова: и посмотри в деюагере на объект t
[13:05:30] Валерия Болотова: ты будешь его разворачивать бесконечно
[13:06:10] Валерия Болотова: это конечно не критично, если перезапск приложения есть. Но при сборке мусора не то что нудевого, но и 2 поколения собрано не будет
[13:07:54] Валерия Болотова: gc - в питоне запускает сборку поколениями типа Gen(o) - разбираем пустые - она быстрая. Есть параметр threashold - там можно установить через сколько циклов 0 сборки запускать 1 и тд. По умолчанию это 1000 сборок. Если приложение написано хорошо, то собирать на 1 поколении нечего. На это не уходит время - память освобождается вовремя
[13:08:18] Валерия Болотова: ща скину пример, когда сборщик при переопределении метода del не собирает мусор вообще
[13:09:51] Валерия Болотова: class TopicWithDel:
def __init__(self):
#наш цикл в упрощении (Без комментов - но это тоже самое)
self.comment = self
def __del__(self):
pass
while True:
TopicWithDel()
[13:10:24] Валерия Болотова: Утечки происходят потому, что Python не знает, используется циклическая ссылка (в нашем случае это self.comment) в методе del. То есть, сборщик мусора не знает в каком месте надо начинать рвать цикл: или (i) сперва удалить ссылку self.comment→self, или (ii) сперва удалить ссылку self→self.comment
[13:10:36] Валерия Болотова: вот о каких циклах идет речь
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment