gc.freeze() поможет экономить память
О нововведении в CPython от инженеров из Instagram.
Около полугода остаётся до выпуска Pyhon 3.7, но уже сейчас по PEP, назначенным в версию, можно составить представление о том, на сколько ожидаемой она получится. Однако предположения по улучшению (PEP), это далеко не всё — в трекере языка на грядующую версию зафиксировано и разрешено множество задач, одной из которых и будет посвящена данная заметка.
Речь идёт о BPO-31558, в рамках которой был реализован новый метод
Допустим у вас есть некий основной процесс, от которого ответвляются (fork) новые процессы. Эти процессы изначально используют память, выделенную для родительского, но только до момента, когда им понадобится изменить её. В этом случае задействуется механизм операционной системы, называемый «копирование-при-записи» (copy-on-write, COW), во время которого для дочернего процесса будет создана копия страниц памяти, подлежащих изменению.
Всё бы хорошо, но сборщик мусора (garbage collector, GC) в Питоне сводит на нет практически всю пользу копирования-при-записи, потому что в ходе сборки обновляет данные в объектах (счётчик ссылок), тем самым провоцируя копирование. Нетрудно догадаться, что в случае наличия большого количества дочерних процессов значительно повысится потребление памяти.
В качестве механизма, позволяющего экономить память в подобных случаях и был предложен новый метод «заморзки» —
Если как можно раньше в жизненном цикле родительского процесса отключить сборку мусора, а потом, после разогрева приложения, вызвать заморозку, то все существующие объекты перейдут в так называемое «неизменное» (permanent) поколение. Объекты в этом поколении не учитываются при последующих сборках мусора. После этого можно вызывать ветвление процесса и снова включать сборку мусора в дочернем процессе.
Будем полагать объекты, порождённые в родительском процессе базовыми, имеющими значение и полезными для дочерних процессов. А коли так, то и произведенные нами действия вполне логичны и позволяют нам качественнее использовать копирование-при-записи.
Где такое может быть полезно? Конечно, в веб-приложениях, ветвящих процессы. А также и в любом долгоживущем приложении, ведь чем дольше оно живёт, тем больше объектов порождает и тем больше времени требуется на сборку мусора.
Помимо метода заморозки появились также:
А начинать морозить будем летом.
Речь идёт о BPO-31558, в рамках которой был реализован новый метод
gc.freeze()
.Допустим у вас есть некий основной процесс, от которого ответвляются (fork) новые процессы. Эти процессы изначально используют память, выделенную для родительского, но только до момента, когда им понадобится изменить её. В этом случае задействуется механизм операционной системы, называемый «копирование-при-записи» (copy-on-write, COW), во время которого для дочернего процесса будет создана копия страниц памяти, подлежащих изменению.
Всё бы хорошо, но сборщик мусора (garbage collector, GC) в Питоне сводит на нет практически всю пользу копирования-при-записи, потому что в ходе сборки обновляет данные в объектах (счётчик ссылок), тем самым провоцируя копирование. Нетрудно догадаться, что в случае наличия большого количества дочерних процессов значительно повысится потребление памяти.
В качестве механизма, позволяющего экономить память в подобных случаях и был предложен новый метод «заморзки» —
gc.freeze()
. Он словно замораживает объекты, делая их недоступными для сборщика.Если как можно раньше в жизненном цикле родительского процесса отключить сборку мусора, а потом, после разогрева приложения, вызвать заморозку, то все существующие объекты перейдут в так называемое «неизменное» (permanent) поколение. Объекты в этом поколении не учитываются при последующих сборках мусора. После этого можно вызывать ветвление процесса и снова включать сборку мусора в дочернем процессе.
Будем полагать объекты, порождённые в родительском процессе базовыми, имеющими значение и полезными для дочерних процессов. А коли так, то и произведенные нами действия вполне логичны и позволяют нам качественнее использовать копирование-при-записи.
Где такое может быть полезно? Конечно, в веб-приложениях, ветвящих процессы. А также и в любом долгоживущем приложении, ведь чем дольше оно живёт, тем больше объектов порождает и тем больше времени требуется на сборку мусора.
Помимо метода заморозки появились также:
- разморозка
gc.unfreeze()
— передвигает объекты из неизменного поколения в старейшее; - подсчёт замороженных
gc.get_freeze_count()
.
На заметку
Подробнее о том, как Жекун Ли и инженеры Instagram пришли к данному решению можно узнать из статьи «Copy-on-write friendly Python garbage collection».
А начинать морозить будем летом.
Категории
Язык
Область
Интерпретатор
Уровень
Аспект языка
На заметку
Зарегистрированные пользователи могут оценивать Книги, Видео, Статьи и прочее, а также добавлять их в избранное, для упрощения доступа к ним в будущем.