Инструкции по реализации
1. Добавьте к объекту счетчик ссылок. Значение счетчика ссылок будет каждый раз где-то увеличиваться. Всякий раз, когда ссылка становится недействительной, счетчик уменьшается на единицу.
Если счетчик ссылок значения переменной уменьшается на единицу и равен 0, значение будет освобождено и не является мусором. Сборщик мусора с этим не справляется.
Если счетчик ссылок значения переменной больше 0 после уменьшения на единицу, значение считается непригодным для освобождения и может стать мусором.
2. Сборщик мусора собирает возможный мусор. После достижения определенного количества он запускает программу идентификации мусора и освобождает настоящий мусор.
Пример
<?php // Случай с механизмом сборки мусора PHP: обратитесь к руководству по PHP //--------------------Скалярный тип-------------------- // совет: каждая переменная PHP существует в контейнере переменных под названием «zval», который содержит тип и значение переменной, «is_ref»: является ли это ссылочной переменной, «refcount»: счетчик ссылок // пример: создать новый zval-контейнер $a = 'new string'; // пример: отображение информации о контейнере zval xdebug_debug_zval('a'); // a: (refcount=1, is_ref=0),string 'new string' (length=10) // пример: увеличить счетчик ссылок zval-контейнера $c = $b = $a; xdebug_debug_zval('a'); // a:(refcount=3, is_ref=0),строка 'новая строка' (длина=10) xdebug_debug_zval('b'); // b:(refcount=3, is_ref=0),строка 'новая строка' (длина=10) xdebug_debug_zval('c'); // c:(refcount=3, is_ref=0),string 'новая строка' (длина=10) // совет: в данный момент существует только один контейнер, потому что PHP не будет копировать сгенерированный контейнер переменных, когда в этом нет необходимости // В настоящее время этот контейнер переменных связан с переменной a, переменной b и переменной c. unset($b); // пример: уменьшить количество ссылок xdebug_debug_zval('a'); // a:(refcount=2, is_ref=0),string 'new string' (length=10) // совет: unset При удалении переменной счетчик переменных refcount уменьшается на единицу. На данный момент только $a и $b указывают на контейнер переменных. не установлено ($ а); не установлено ($ с); var_dump ($ а); // Совет: в этот момент пересчет равен 0, и переменная удаляется // Когда пересчет становится равным 0, контейнер переменных, содержащий тип и значение, будет удален из памяти. //--------------------Композитный тип------------- echo '--------------Составной тип ------------<br/>'; $а = массив( 'имя' => 'младший', 'возраст' => 18 ); xdebug_debug_zval('а'); // а:(refcount=1, is_ref=0), // массив (размер=2) // 'name' => (refcount=1, is_ref=0), строка 'младший' (длина=6) // 'возраст' => (refcount=1, is_ref=0),int 18 // пример: добавить существующий элемент в массив $a['love'] = $a['name']; xdebug_debug_zval('а'); // а:(refcount=1, is_ref=0), // массив (размер=3) // 'name' => (refcount=2, is_ref=0), строка 'младший' (длина=6) // 'возраст' => (refcount=1, is_ref=0),int 18 // 'любовь' => (refcount=2, is_ref=0), строка 'младший' (длина=6) // $a = массив('один'); // xdebug_debug_zval('a'); // // $b = &$a; // $с = $а; // $b = &$c; // xdebug_debug_zval('b'); // xdebug_debug_zval('c'); // xdebug_debug_zval('a'); // Устранение проблемы с контейнером переменных echo '------------Проблема утечки памяти -----------<br/>'; $а = массив('один'); xdebug_debug_zval('а'); // а:(refcount=1, is_ref=0), // массив (размер=1) // 0 => (refcount=1, is_ref=0), строка 'один' (длина=3) $a[] = &$a; xdebug_debug_zval('а'); // а:(refcount=2, is_ref=1), // массив (размер=2) // 0 => (refcount=1, is_ref=0), строка 'один' (длина=3) // 1 => (refcount=2, is_ref=1), // &множество // не установлено ($а); // (refcount=1, is_ref=1)=массив ( // 0 => (refcount=1, is_ref=0)='one', // 1 => (refcount=1, is_ref=1)=... // ) // совет: после unset($a) счетчик ссылок уменьшается на единицу, даже если в области видимости больше нет символа, указывающего на эту структуру (то есть контейнер переменных), // Поскольку элемент массива «1» все еще указывает на сам массив, этот контейнер не может быть очищен // Поскольку нет другого символа, указывающего на него, у пользователя нет возможности очистить эту структуру, что приводит к утечке памяти // К счастью , PHP будет Эта структура данных очищается в конце выполнения скрипта, но прежде чем PHP очистит ее, будет использовано много памяти. // То же самое происходит и с объектами, на самом деле с объектами это происходит с большей вероятностью, поскольку на объекты всегда ссылаются неявно.
Выше описано, как подсчет ссылок PHP реализует сбор мусора. Надеюсь, это будет полезно всем.