При попытке проследить некоторые проблемы с памятью в PHP я заметил, что debug_backtrace()
, который я вызываю в своем коде регистрации, как представляется, использует много памяти.
В большинстве случаев следующий код печатает примерно 0.02 MB
. Но в одном случае он печатает 171.85 MB
!
$before = memory_get_usage(); $backtrace = debug_backtrace(false); $after = memory_get_usage(); echo round(($after - $before)/1024/1024, 2)." MB";
Мой вопрос в том, означает ли это, что debug_backtrace
фактически использует столько памяти? Или может произойти что-то еще, например, сборка мусора, которая memory_get_usage
возвращаемое значение из memory_get_usage
?
Его объекты, скорее всего, вызывают раздувание. Попробуйте передать false
функции, чтобы вы не тянули объекты, а ваши трассы будут намного меньше.
EDIT: если передача false
не работает, то, если вы используете PHP 5.3.6+, вы можете использовать битмаску, чтобы ограничить то, что возвращает функция. Похоже, что у вас есть объекты, которые передаются как огромные аргументы.
http://php.net/manual/en/function.debug-backtrace.php Ссылка
Кроме того, если вы используете PHP 5.4.0+, они добавили второй параметр, который позволит вам ограничить количество кадров стека.
EDIT2: итого << HACK >> здесь, но работает … добавьте try / catch, выбросьте исключение и поймайте его, затем преобразуйте в строку или вызовите исключение getTraceAsString (), чтобы получить полный стек. Пример:
try { throw new Exception('ignore this string'); } catch(Exception $e) { /* @var $trace array */ $trace = $e->getTrace(); // OR /* @var $str string */ $str = $e->getTraceAsString(); $e = null; }
В приведенном выше фрагменте вы можете использовать $trace
и создавать собственный вывод или просто использовать стандартное исключение как строку $str
. Легче получить вывод кадра стека.
Хорошо, я думаю, что понял. Я распечатал backtrace, и массив "args"
был огромным. Это потому, что я проходил мимо огромных струн. Я предполагаю, что он копирует их (вместо ссылок) при возвращении результатов.
Например:
function test($str) { test2($str); } function test2($str) { test3($str); } function test3($str) { echo "before: ".round(memory_get_usage()/1024/1024, 2)." MB\n"; debug_backtrace(false); echo "after: ".round(memory_get_usage()/1024/1024, 2)." MB\n"; } test(str_repeat('a', 10000000));
Попробуйте это с вызовом debug_backtrace () и без него. При этом использование памяти увеличивается примерно на 28 МБ. Он очищается только при возврате test3 ().
Если ваш код, например, рекурсивный, и вы глубоко погружены в рекурсию, backtrace должен будет хранить данные для каждой рекурсии …