Как «развернуть» memory_get_usage () в PHP, чтобы найти утечки памяти? - PullRequest
0 голосов
/ 16 марта 2012

У меня есть скрипт, который иногда ломается, потому что я получаю сообщение об ошибке:

PHP Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes) in ...

Ограничение памяти НЕ слишком мало и было установлено на 128M.(Этого должно быть более чем достаточно.)

Проблема в том, что при выполнении сценария требуется все больше и больше памяти.По сути, это цикл for.Я проверил каждую переменную, но нет места, где скрипт заполняет «что-то» (например, массив), которое будет расти и объяснять, почему скрипт занимает больше памяти.

Я подтвердил проблему с памятью, используя:memory_get_usage().Я напечатал след памяти после каждой итерации, и число всегда увеличивается.

Использование Xdebug не показывает никаких признаков, которые могут мне помочь в этом моменте.

Есть ли способ, которым яможет развернуть и узнать, что занимает больше памяти каждый раз, когда я зацикливаюсь?Что бы вы предложили для устранения этой ситуации?

1 Ответ

0 голосов
/ 16 марта 2012

Краткий ответ: детализация невозможна.

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

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

Наконец-то я обнаружил, что вызываю функцию, которая использует create_function из PHP.Многие люди «жалуются» на «утечки памяти» из-за этой функции.Проблема заключается не в утечке памяти, а в том, что если вы вызовете create_function в цикле, он действительно создаст столько функций, сколько вы выполняете цикл.Чтобы избежать этого, я нашел эту концепцию, чтобы избежать повторного создания функции тысячи раз.

<?php 
global $my_func; 
if (!isset($my_func)) { 
    $my_func = create_function($args, $code); 
}

$my_func(); 
?>

Адаптация кода для обеспечения создания функции только после того, как проблема решена.Весь сценарий теперь занимает всего 8 МБ памяти вместо того, чтобы ломаться после перебора более 128 МБ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...