Недавно встретился хороший пост для начинающих о сборке мусора (он же
Начнем с того, что так как php - язык интерпретируемый, то вам не нужно заморачиваться управлением памятью - выделением памяти, и что более важно - очисткой памяти. Этим в php занимается специальный механизм, называемый сборкой мусора (или garbage collection, или же gc).
Сборка мусора работает тремя способами:
В данном коде:
- С подсчетом ссылок разобраться чуть сложнее. Официальная часть здесь.
Кратко - для того чтобы понять, можно ли безопасно собрать переменную с помощью garbage collection, используется механизм подсчета ссылок. Данный механизм заключается в следующем - при создании переменной в php создается не просто переменная, а контейнер типа
Как только в какой-то момент переменная удаляется (с помощью
Мониторить состояние контейнера можно при наличии расширения Xdebug с помощью функции
- Сборка мусора при наличии циклических ссылок не так сложна, как предыдущий пункт. В этом случае сборка мусора активируется в тот момент, когда в памяти находится 10000 объектов с циклическими ссылками, и один из них уходит из области видимости. Значение 10000 установлено на уровне ядра php и может быть изменено только путем изменения исходного кода и его перекомпиляции. Однако, процесс сборки мусора можно запустить явно, не дожидаясь накопления 10000 объектов, с помощью метода
Также, так как сборка мусора при наличии циклических ссылок может потребовать значительное количество ресурсов, то такую сборку можно запретить одним из двумя способов:
Также можно отметить, что изменения в php7.3 серьезно улучшили механизм сборки мусора - в оригинальном посте можно увидеть бенчмарки сравнения предыдущих релизов и версии 7.3, плюс появилась полезная функция gc_status, выводящая данные об использовании gc. А при наличии уже упомянутого Xdebug можно получить еще больше информации с помощью функции
Вот все основные моменты, что следует знать и помнить о сборке мусора. Оригинальная статья с некоторыми дополнительными плюшками - тут.
garbage collection
) в php. Далее я попытаюсь перевести этот пост на русский и добавить немного собственных данных. Ссылка на оригинальный пост - в конце.Начнем с того, что так как php - язык интерпретируемый, то вам не нужно заморачиваться управлением памятью - выделением памяти, и что более важно - очисткой памяти. Этим в php занимается специальный механизм, называемый сборкой мусора (или garbage collection, или же gc).
Сборка мусора работает тремя способами:
- При уходе переменной из области видимости
- При подсчете ссылок
- При сборе циклических ссылок
unset
можно явно определить, что переменную пора собирать gc
. Пример кода:
function display_var() {
$foo = "bar";
echo $foo;
}
$user = "Mister X";
unset($user);
В данном коде:
- переменная
$foo
будет автоматически собрана gc сразу после завершения выполнения функцииdisplay_var
- переменная
$user
будет собрана gc, так как она явно удалена с помощьюunset
- С подсчетом ссылок разобраться чуть сложнее. Официальная часть здесь.
Кратко - для того чтобы понять, можно ли безопасно собрать переменную с помощью garbage collection, используется механизм подсчета ссылок. Данный механизм заключается в следующем - при создании переменной в php создается не просто переменная, а контейнер типа
zval
, в котором помимо собственно типа и значения переменной, хранится еще два поля - ref_count
и is_ref
. Далее, если вы присваиваете другой переменной значение этой переменной, то контейнер не копируется с имеющимися данными, а php просто увеличивает ref_count
на единицу, так как контейнер используется уже двумя переменными. И так далее.Как только в какой-то момент переменная удаляется (с помощью
unset
или ухода из зоны видимости), счетчик ref_count
в контейнере уменьшается. Как только счетчик дошел до нуля - считается, что контейнер готов к сборке мусора.Мониторить состояние контейнера можно при наличии расширения Xdebug с помощью функции
xdebug_debug_zval
.- Сборка мусора при наличии циклических ссылок не так сложна, как предыдущий пункт. В этом случае сборка мусора активируется в тот момент, когда в памяти находится 10000 объектов с циклическими ссылками, и один из них уходит из области видимости. Значение 10000 установлено на уровне ядра php и может быть изменено только путем изменения исходного кода и его перекомпиляции. Однако, процесс сборки мусора можно запустить явно, не дожидаясь накопления 10000 объектов, с помощью метода
gc_collect_cycles
.Также, так как сборка мусора при наличии циклических ссылок может потребовать значительное количество ресурсов, то такую сборку можно запретить одним из двумя способов:
- вызвать метод
gc_disable
- установить значение
zend.enable_gc
вfalse
в файле php.ini (gc_disable
делает то же самое)
Также можно отметить, что изменения в php7.3 серьезно улучшили механизм сборки мусора - в оригинальном посте можно увидеть бенчмарки сравнения предыдущих релизов и версии 7.3, плюс появилась полезная функция gc_status, выводящая данные об использовании gc. А при наличии уже упомянутого Xdebug можно получить еще больше информации с помощью функции
xdebug_start_gcstats
.
Вот все основные моменты, что следует знать и помнить о сборке мусора. Оригинальная статья с некоторыми дополнительными плюшками - тут.
Комментариев нет:
Отправить комментарий