Где найти "низкую память" и "свободные циклы процессора" вызывает запуск сбора мусора на unset()?

Я часто нахожу ссылки на следующую цитату, используемую при объяснении того, что PHP unset() не запускает "сборку мусора" немедленно, но только тогда, когда она сочтет нужным (выделение мое):

unset() делает то, что он называет - отключить переменную. Это не приводит к немедленному освобождению памяти. РНР сборщик мусора сделает это, когда он см. припадки - по желанию, как только эти циклы ЦП не нужны в любом случае, или еще до того, как script закончится память, что бы ни происходило первый.

Если вы делаете $whatever = null; то вы переписываете переменную данные. Вы можете освободить память/ быстрее сокращается, но может красть процессор циклов из кода, который действительно нужен их раньше, в результате чего общее время выполнения.

Я хочу знать, как работает код C для этого цикла "низкая память" и "свободный цикл процессора", запускающий сборку мусора, и отличается ли она от PHP 5.2.x и PHP 5.3 +.

Итак, я загрузил исходные файлы C PHP 5.2.17 и попытался найти правильные разделы кода. Может быть, я просто слепой, или мои навыки С слишком низки, но я не смог найти такой код.

Может кто-нибудь указать мне на правильные файлы C, пожалуйста?

ИЗМЕНИТЬ

При поиске примеров использования приведенной выше цитаты я понял что-то странное.

Некоторые примеры, например qaru.site/info/30116/..., ссылаются на эту цитату, используя следующий URL-адрес для комментария на php.net: http://us2.php.net/manual/en/function.unset.php#86347.

Просмотр этого URL-адреса показывает только верхнюю часть руководства unset(). Комментарий # 86347 отсутствует.

Проверка машины обратного пути показывает, что этот комментарий DID существует с октября 2008 года, но исчезли где-то в сентябре или после сентября 2012 года (причина неизвестна).

Может быть, эта цитата и всегда была просто неправильной?

Или есть кто-нибудь, кто может указать мне на правильные файлы C?

Ответ 1

ОК, так что время для некоторых PHP Mythbusters! Пожалуйста, начните с чтения документации PHP о том, как работает сбор мусора, поскольку я собираюсь предположить некоторые предварительные знания о том, как это все работает:

Второй документ специально объясняет, что запускает циклический сборщик мусора. Он не имеет ничего общего с "свободными циклами процессора" или "низкой памятью" - он полностью основан на количестве потенциальных объектов мусора, которые присутствуют:

Когда сборщик мусора включается, алгоритм поиска циклов, как описано выше, выполняется всякий раз, когда корневой буфер заполняется. Корневой буфер имеет фиксированный размер 10000 возможных корней.

То есть циклический сборщик мусора запускается в любое время, когда определенное количество потенциально мусорных объектов накапливается независимо от размера этих объектов. Рассмотрение кода в zend_gc.c подтверждает это - там, конечно, ничего не происходит, проверяя общий объем свободной памяти, и, безусловно, ни один из которые потребуются для выполнения GC, пока процессор свободен. Поэтому я думаю, что мы можем назвать эту часть "разоренной".


Далее, давайте посмотрим, какова может быть фактическая разница между $x = null и unset($x). Во-первых, позвольте подтвердить, что они делают то же самое, используя этот класс, как наш Buster Test Dummy:

class NoisyDestructor {
    function __destruct() {
        print "Destructor called\n";
    }
}

Теперь посмотрим, какая разница между установкой переменной в null и unset() -ing:

$x = new NoisyDestructor();
print "Created\n";
$x = null;
print "Nulled\n";

print "\n";

$x = new NoisyDestructor();
print "Created\n";
unset($x);
print "Unset\n";

Когда мы запускаем это, мы видим:

Created
Destructor called
Nulled

Created
Destructor called
Unset

Подождите минуту, чтобы точно такая же последовательность для обоих! Там нет функциональной разницы между ними. Теперь, как насчет производительности?

class Thing { }

$start = microtime(true);
for ($i = 0; $i < 1e6; $i++) {
    $x = new Thing();
    $x = null;
}
printf("%f sec for null\n", microtime(true) - $start);

$start = microtime(true);
for ($i = 0; $i < 1e6; $i++) {
    $x = new Thing();
    unset($x);
}
printf("%f sec for unset\n", microtime(true) - $start);

Теперь, используя мой ноутбук для тестирования, с PHP 5.4, я получаю:

0.130396 sec for null
0.175086 sec for unset

Не только разница в производительности между установкой переменной на нуль и ее установкой довольно незначительной, учитывая, сколько раз нам приходилось запускать этот цикл, чтобы увидеть этот результат, но на самом деле это противоположная что утверждал этот комментарий: unset() примерно на 25% медленнее! Этот миф PHP был хорошо и действительно разорен.

BUSTED

TL; DR. Цитата, которую вы нашли, совершенно неверна. (По всей видимости, он был удален из PHP.net по этой причине.)