
Инструкции по реализации
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 реализует сбор мусора. Надеюсь, это будет полезно всем.