Why does debug_backtrace () use so much memory?

While trying to trace some memory issues in PHP, I noticed that the debug_backtrace() that I call in my logging protocol seems to be using a lot of memory.

In most cases, the following code prints something like 0.02 MB . But in one case, it prints 171.85 MB !

 $before = memory_get_usage(); $backtrace = debug_backtrace(false); $after = memory_get_usage(); echo round(($after - $before)/1024/1024, 2)." MB"; 

My question is, does this mean that debug_backtrace actually uses that much memory? Or could something else happen, such as garbage collection, which messed up the return value from memory_get_usage ?

+4
source share
3 answers

Well, I think I figured it out. I printed the backtrace and the "args" array was huge. This is because I walked past huge strings. I think that when copying the results they copy (instead of links).

For instance:

 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)); 

Try this with and without calling debug_backtrace (). At the same time, memory usage is increased by approximately 28 MB. It is cleared only when test3 () returns.

+4
source

Its objects are likely to cause bloating. Try passing false functions so that you don’t stretch objects and your traces will be much smaller.

EDIT: If passing false does not work, then if you are using PHP 5.3.6+, you can use a bitmask to restrict the returned function. It looks like you have objects that are passed as huge arguments.

http://php.net/manual/en/function.debug-backtrace.php Link

In addition, if you are using PHP 5.4.0+, they have added a second parameter, which will allow you to limit the number of stack frames.

EDIT2: total < HACK β†’ here, but it works ... add try / catch, throw an exception and catch it, then convert to a string or call getTraceAsString () exception to get the full stack. Example:

 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; } 

In the above snippet, you can use $trace and create your own output, or simply use the standard exception as the string $str . It’s easier to get the output of the stack frame.

+7
source

If your code, for example, is recursive, and you are deep in recursion, backtrace will have to store data for each recursion ...

+2
source

Source: https://habr.com/ru/post/1342065/


All Articles