Подтвердить что ты не робот

Почему PHP НЕ очищает память после выхода из цикла?

for($i=0; $i<3; $i++) {
    echo '$i = ' . $i . '<br/>' ;
}
echo 'out of loop, $i = ' . $i;

приведенные выше выходы:

$i = 0
$i = 1
$i = 2
out of loop, $i = 3

Мне не имеет смысла, что $i все еще отображается даже после отображения его из области цикла. Почему это происходит (в java он автоматически собирает мусор)?

И есть ли способ сказать php автоматически делать сборку мусора после выхода из цикла? Мой код выглядит уродливым, когда я должен вызывать unset() после каждого цикла.

4b9b3361

Ответ 1

Это не о сборке мусора, а о сфере видимости.

В PHP для циклов не создается их собственная область. $i создается в той же области, что и цикл, поэтому он все еще существует после завершения цикла. Это не будет мусором, собранным больше, чем переменная, которую вы объявляете на линии до того, как цикл будет.

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

Если вы вручную измените переменную unset, вы можете принудительно удалить сборку мусора с gc_collect_cycles с PHP 5.3.

Ответ 2

Из Переменная область

Объем переменной - это контекст, в котором он определен. По большей части все переменные PHP имеют только одну область. В эту единую область охвата включены и требуемые файлы. [...] В пользовательских функциях вводится локальная функция. Любая переменная, используемая внутри функции, по умолчанию ограничена областью локальной функции.

Переменная не будет собираться мусором, потому что у вас все еще есть ссылка на $i в области после выхода из цикла. Обратите внимание, что использование unset не будет делать сборку мусора, но это будет означать, что память больше не ссылается на Garbage Collector для сбора в следующий раз GC запускается. Вы можете заставить сбор мусора gc_collect_cycles.

Ответ 3

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

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