Диагностика утечек памяти - допустимый объем памяти исчерпан # байтами - PullRequest
92 голосов
/ 11 мая 2009

Я столкнулся с ужасным сообщением об ошибке, возможно, из-за кропотливых усилий, PHP исчерпал память:

Допустимый объем памяти в #### байтах исчерпан (попытался выделить #### байтов) в file.php в строке 123

Увеличение лимита

Если вы знаете, что делаете, и хотите увеличить лимит, см. memory_limit :

ini_set('memory_limit', '16M');
ini_set('memory_limit', -1); // no limit

Осторожно! Вы можете решить только симптом, а не проблему!

Диагностика утечки:

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

foreach ($users as $user) {
    $task = new Task;
    $task->run($user);
    unset($task); // Free the variable in an attempt to recover memory
    print memory_get_usage(true); // increases over time
}

Для целей этого вопроса давайте предположим, что худший код спагетти, который только можно себе представить, прячется в глобальном масштабе где-то в $user или Task.

Какие инструменты, трюки PHP или отладка voodoo могут помочь мне найти и исправить проблему?

Ответы [ 13 ]

2 голосов
/ 12 мая 2009

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

1 голос
/ 06 января 2012

Я немного опоздал к этому разговору, но поделюсь чем-то подходящим для Zend Framework.

У меня возникла проблема утечки памяти после установки php 5.3.8 (с использованием phpfarm) для работы с приложением ZF, разработанным с использованием php 5.2.9. Я обнаружил, что утечка памяти была вызвана в файле Apache httpd.conf, в моем определении виртуального хоста, где написано SetEnv APPLICATION_ENV "development". После комментирования этой строки утечки памяти прекратились. Я пытаюсь найти встроенный обходной путь в моем php-скрипте (в основном, определяя его вручную в основном файле index.php).

0 голосов
/ 08 сентября 2017

Я не видел здесь упомянутое, но одна вещь, которая может быть полезна, - это использовать xdebug и xdebug_debug_zval ('variableName'), чтобы увидеть счетчик ссылок.

Я также могу привести пример расширения php: Z-Ray Zend Server. Если сбор данных включен, использование памяти будет увеличиваться на каждой итерации так же, как если бы сборка мусора была отключена.

...