сборка мусора php при запуске скрипта

У меня есть PHP-скрипт, который работает на cron, который может занять до 15 минут. Через равные промежутки времени я выплевываю memory_get_usage (), чтобы я мог видеть, что происходит. В первый раз, когда он говорит мне, что я использую, я нахожусь в 10 мегабайтах. Когда сценарий заканчивается, я нахожусь в 114 мегабайтах!

Выполняет ли PHP сборку мусора во время работы скрипта? Или что происходит со всей этой памятью? Есть ли что-то, что я могу сделать, чтобы заставить сбор мусора. Задача, которую выполняет мой скрипт, – это ночной импорт нескольких тысяч узлов в Drupal. Так что он делает то же самое много раз.

Какие-либо предложения?

Ключ в том, что вы отключите свои глобальные переменные, как только они вам не понадобятся.

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

PHP сохраняет количество ссылок для всех переменных и уничтожает их (в большинстве условий), как только этот счетчик ссылок будет равен нулю. Объекты имеют один внутренний счетчик ссылок, а сами переменные (ссылки на объекты) имеют один счетчик ссылок. Когда все ссылки на объекты были уничтожены, потому что их ссылочные coutns достигли 0, сам объект будет уничтожен. Пример:

$a = new stdclass; //$a zval refcount 1, object refcount 1 $b = $a; //$a/$b zval refcount 2, object refcount 1 //this forces the zval separation because $b isn't part of the reference set: $c = &$a; //$a/$c zval refcount 2 (isref), $b 1, object refcount 2 unset($c); //$a zval refcount 1, $b 1, object refcount 2 unset($a); //$b refcount 1, object refcount 1 unset($b); //everything is destroyed 

Но рассмотрим следующий сценарий:

 class A { public $b; } class B { public $a; } $a = new A; $b = new B; $a->b = $b; $b->a = $a; unset($a); //cannot destroy object $a because $b still references it unset($b); //cannot destroy object $b because $a still references it с class A { public $b; } class B { public $a; } $a = new A; $b = new B; $a->b = $b; $b->a = $a; unset($a); //cannot destroy object $a because $b still references it unset($b); //cannot destroy object $b because $a still references it 

Эти циклические ссылки – это то, где gc_collect_cycles сборщик мусора PHP 5.3. Вы можете явно вызвать сборщик мусора с помощью gc_collect_cycles .

См. Также « Основы подсчета ссылок» и « Циклы сбора» в руководстве.

Сбор мусора PHP в значительной степени является эталонным счетчиком (у него есть некоторое обнаружение цикла). Если вы сохраняете ссылки, которые все еще доступны, они легко складываются, если не освобождаются.

Используйте unset () для освобождения переменных, которые вы больше не используете. Если вы просто перезаписываете переменные (например, с нулевым), это позволит GC уменьшить до объема пространства, требуемого этой переменной, но не так сильно, как unset, что фактически позволяет уничтожить ссылочное значение.

Вы также должны правильно выпускать любые ресурсы и т. Д., Которые вы используете.

Вы по-прежнему будете видеть увеличение памяти во время выполнения, так как GC может свободно выпускать его при своей собственной дискреции, например, когда есть бесплатные циклы процессора или когда он начинает работать на низкой памяти.

Используйте unset() как можно больше, чаще проверяйте используемую память. да, php делает сборку мусора во время выполнения на нескольких условиях. здесь полезный пост на php.net.

Если память увеличивается настолько сильно, то вы, вероятно, не выпускаете ее. Вы создали утечку памяти. Сбор мусора не поможет вам, если вы не отключите переменные, не уничтожьте объекты и / или не выйдете из сферы действия.

Вы отключаете узлы, которые вы загружаете, когда закончите с ними? Я написал PHP-скрипты, которые работают часами, обрабатывая миллионы записей базы данных, без проблем и использования памяти, которые поднимаются и опускаются в очень приемлемом диапазоне.