简体   繁体   中英

Track memory usage of a method

I have yet to find an elegant solution for this. I have a class with a method I want to track the memory usage of without modifying the function:

class Example
{
    public function hello($name)
    {
        $something = str_repeat($name, pow(1024, 2));
    }
}

$class = new Example;
$class->hello('a');

So the task is, how much memory does hello() use without interferring with it?

Note: The memory usage of this method should be 1MB. I've tried wrapping the call with memory_get_usage(); to no avail:

class Example
{
    public function hello($name)
    {
        $something = str_repeat($name, pow(1024, 2));
    }
}

$class = new Example;

$s = memory_get_usage();

$class->hello('a');

echo memory_get_usage() - $s;

This only results in 144 bytes (Not correct at all). I've tried various magic with Reflection by using the ReflectionMethod class.

I have a feeling what I need to do is calculate the difference in the method :(. If someone can think of anything cleaner then you'd really make my day.

Edit: I should mention this is in the context of a benchmarking application. So while memory_get_peak_usage works in the sense that it correctly returns the memory usage, it will also skew benchmarks ran after a high memory method. Now if there was a way to reset the memory stats, that could be good also.

You could use register_tick_function and just dump memeory_get_usage out every tick (line) and analysis it later. The class below could be improved by using debug_backtrace to find line number related to memory usage or adding time per line using microtime .

Profiler class

class Profiler
{

    private $_data_array = array();

    function __construct()
    {
        register_tick_function( array( $this, "tick" ) );
        declare(ticks = 1);
    }

    function __destruct()
    {
        unregister_tick_function( array( $this, "tick" ) );
    }

    function tick()
    {
        $this->_data_array[] = array(
            "memory" => memory_get_usage(),
            "time" => microtime( TRUE ),
            //if you need a backtrace you can uncomment this next line
            //"backtrace" => debug_backtrace( FALSE ),
        );
    }

    function getDataArray()
    {
        return $this->_data_array;
    }
}

Example

class Example
{
    public function hello($name)
    {
        $something = str_repeat($name, pow(1024, 2));
    }
}

$profiler = new Profiler(); //starts logging when created

$class = new Example;
$class->hello('a');

$data_array = $profiler->getDataArray();

unset( $profiler ); //stops logging when __destruct is called

print_r( $data_array );

Output

Array (
    [0] => Array (
            [memory] => 638088
            [time] => 1290788749.72
        )
    [1] => Array (
            [memory] => 638896
            [time] => 1290788749.72
        )
    [2] => Array (
            [memory] => 639536
            [time] => 1290788749.72
        )
    [3] => Array (
            [memory] => 640480
            [time] => 1290788749.72
        )
    [4] => Array (
            [memory] => 1689800 // <~ money!
            [time] => 1290788749.72
        )
    [5] => Array (
            [memory] => 641664
            [time] => 1290788749.72
        )
)

Possible Issue

Since this profiler class stores the data in PHP, the overall memory usage will increase artificially. One way to sidestep this issue would be to write the data out to a file as you go (serialized), and when your done you can read it back.

由Facebook 专家开发的XHProfLive剖析器提供了这种程度的功能/方法级别的剖析,并且可以通过PECL下载获得

The memory is released when you are returning from the function.

You might add the $s = memory_get_usage(); ... echo memory_get_usage() - $s; $s = memory_get_usage(); ... echo memory_get_usage() - $s; block inside of the function. This way, the memory used will not be released.

It looks like it has already 'freed up' memory after the call to hello() has ended.

What are the results when you do:

$s = memory_get_usage();

$class->hello('a');

echo memory_get_peak_usage() - $s;

You should use a php memory tool.

There is a nice one to be found in this SO thread: Tools to visually analyze memory usage of a PHP app

this other question holds some further answers regarding your question

The only trustable method I know to achieve this is profiling with tools that are not written in php itself.

Read this:

http://www.xdebug.org/docs/profiler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM