Comments 18
Отличная статья, коллега!
Спасибо за статью, Сергей!
Дополнительным эффектом бессмертных объектов является отсутствие записи в счетчик ссылок, а значит, отсутствие необходимости обновлять кеши
CPU
, что отобразится в более эффективных паттернах работы с памятью для таких объектов.
В функцию Py_INCREF добавился if, причем обычно не выполняющийся (исходя из предположения, что большинство объектов не бессмертные). Навскидку бы сказал, что в этом основная причина деградации по скорости
Всё по делу, всё понятно) По крайней мере для тех, кто тоже любит покопаться в исходниках) Автор, пиши ещё))
Спасибо за статью!
Чего только не придумают вместо нормального сборщика мусора с маркировкой.
Как бы нормальный сборщик мусора с маркировкой а) работал бы в этом случае (см. причины появления) б) как бы он был обратно совместим?
У сборщика с маркировкой нет счётчика ссылок, поэтому нет и указанных проблем. Что касается обратной совместимости, то я надеюсь, что на питоне немного программ, завязанных на конкретное устройство сборщика мусора.
Проблема в том, что Py_INCREF/Py_DECREF
как рак пронизывают не только весь CPython, но и все C-расширения - т.е. отказ от подсчета ссылок это слом обратной совместимости, боюсь что даже 4.0 на такое не пойдет. Так что ваше предложение потребует переписать весь CPython. Не спорю, это было бы интересно, но кто будет платить за банкет, не понятно.
Потом, как показывает практика, на sys.getrefcount ссылаются в программах.
Подсчета ссылок нет в PyPy
, например. Не смотря на то что это Python, это все таки в меньшей степени Python.
вернуть объект в мир смертных
_Py_SetMortal
Но зачем? И как это сделать, если мы без понятия сколько ссылок на объект, поскольку не считали их для бессмертного объекта?
Вы задаете правильный вопрос - зачем. Самый простой ответ выполнить очистку/удаление/финализацию (называйте как хотите) объекта. Т.к. бессмертные объекты сейчас в основном внутренние системные объекты, то мы можем знать когда на эти объекты не осталось ссылок. В этом случае мы можем выполнить `_Py_SetMortal(op, 1)` и после этого `Py_DECREF(op)` чтобы очистить объект. Понятно, что это не относится к accidentally immortal объектам - они у нас просто утекут в данный момент. Думаю что PEP 797 в каком-то виде ответит на эти вопросы, стоит немного подождать.
CPython — бессмертные Immortal объекты