Сборщик мусора (GC) — это система управления внутренней памятью в PHP, но здесь необходимо понимать некоторые тонкости.
GC автоматизирует управление памятью, что устраняет необходимость обработки памяти с помощью ручных задач (что было бы утомительно).
Это позволяет разработчикам сосредоточиться на своей бизнес-логике, не беспокоясь чрезмерно об ошибках «Недостаточно памяти».
Конечно, это не волшебство.
Освобождение объектов, которые больше не нужны, предотвращает утечку памяти.
Сборщик мусора использует механизм подсчета для определения элементов, которые необходимо удалить. Если никакие ссылки не указывают на конкретный объект (т. е. $counter = 0), то этот объект подлежит очистке.
Это работает довольно хорошо, но некоторые ссылки могут вызывать проблемы:
class A { public $b; } class B { public $a; } $a = new A(); $b = new B(); $a->b = $b; $b->a = $a; unset($a); unset($b);
В этом случае плохого дизайна PHP не освободит память, даже если мы отключим $a и $b, поскольку они ссылаются друг на друга, что заставляет PHP думать, что они все еще используются.
К счастью, для этого существует другой механизм, называемый сборщиком циклов:
gc_collect_cycles();
Грубо говоря, сборщик просматривает все ссылки и применяет алгоритм для маркировки используемых объектов, который обнаруживает объекты для сбора (немаркированные).
Однако PHP не запускает автоматический циклический сбор до тех пор, пока не будет достигнуто пороговое значение в 10 000 объектов с потенциальными циклическими ссылками.
Опять же, это не волшебство, поэтому вызывать gc_collect_cycles() нужно лишь в редких случаях.
Плохой дизайн может привести к слишком сложным отношениям между объектами, что приведет к увеличению количества ссылок и более частой сборке мусора.
Каждый объект с подсчетом ссылок требует дополнительного хранилища для своего счетчика ссылок.
Источник: Википедия – подсчет ссылок
Накладные расходы, связанные с операциями очистки памяти, могут существенно повлиять на глобальную производительность и в конечном итоге увеличить время выполнения в определенных сценариях.
10 лет назад Composer получил огромный прирост производительности, просто используя функцию gc_disable().
Источник: Composer – отключение GC
Действительно, PHP 7 значительно улучшил сборщик мусора, так что он уже не тот, что был в 2014 году.
Кроме того, в версиях PHP 8 улучшены стратегии распределения памяти и добавлено больше полезной статистики об операциях сборщика мусора для лучшего мониторинга (gc_status() в 8.3).
Большинство PHP-приложений управляются запросами, и память автоматически очищается в конце запроса.
Опять же, это довольно круто, но не волшебно. Что происходит с асинхронными запросами и долгоживущими объектами/демонами?
В какой-то момент могут возникнуть утечки памяти.
На этом этапе вы, возможно, не видите, чем сборщик мусора PHP отличается от других языков.
В большинстве случаев другие языки не используют подсчет ссылок для сбора мусора или могут использовать другие реализации.
Например, многие используют алгоритм трассировки, который также отмечает неиспользуемые объекты, но не работает постепенно. Это обход графа.
Кроме того, некоторые языки не допускают такого прямого управления (например, включение/выключение во время выполнения).
Как обычно, есть свои преимущества и неудобства, поэтому вы можете увидеть некоторые гибридные подходы.
Вы можете использовать встроенные помощники gc_*.
Например:
Эти функции полезны для отладки или тонкой настройки сборки мусора при необходимости.
Чтобы получить дополнительную информацию, вы можете прочитать этот пост:
В PHP 7.4 появились слабые ссылки, а в PHP 8 — слабые карты.
Слабую карту можно описать как набор слабых ссылок.
Эта структура данных представляет собой универсальное хранилище значений ключей, которое помогает PHP отслеживать элементы, не создавая беспорядка и не занимая лишнего места.
Вы можете рассматривать его как временное хранилище, которое будет сразу же очищено, когда оно больше не понадобится, поскольку нет [строгих] ссылок, которые могли бы помешать сборке мусора:
$object = new stdClass; $map = new WeakMap(); $map[$object] = true; $object->name = 'some name'; print_r($map);// $object is stored in $map unset($object); print_r($map);// $object is cleaned and no longer available
В большинстве случаев вам не придется беспокоиться об управлении памятью, поскольку PHP уже с этим справляется.
Однако, поскольку современные стеки используют долгоживущие объекты, вам необходимо отслеживать приложение на предмет потенциальных утечек памяти.
Если у вас возникнут проблемы, возможно, вам придется оптимизировать код и/или напрямую взаимодействовать с сборщиком мусора.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3