简体   繁体   English

跟踪方法的内存使用情况

[英]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? 因此,任务是, hello()在不干涉的情况下使用了多少内存?

Note: The memory usage of this method should be 1MB. 注意:此方法的内存使用量应为1MB。 I've tried wrapping the call with memory_get_usage(); 我试过用memory_get_usage();包装该调用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). 这只会导致144个字节(完全不正确)。 I've tried various magic with Reflection by using the ReflectionMethod class. 我已经通过使用ReflectionMethod类使用了ReflectionMethod尝试了各种魔术。

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. 因此,虽然memory_get_peak_usage在正确返回内存使用量的意义上起作用,但它也会在高内存方法后偏向运行基准测试。 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. 您可以使用register_tick_function并仅将memeory_get_usage转储出每个刻度(行)并在以后进行分析。 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 . 通过使用debug_backtrace查找与内存使用相关的行号或使用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. 由于此事件探查器类将数据存储在PHP中,因此总的内存使用量将人为增加。 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; $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. 在hello()调用结束后,它似乎已经“释放”了内存。

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. 您应该使用php记忆工具。

There is a nice one to be found in this SO thread: Tools to visually analyze memory usage of a PHP app 在该SO线程中可以找到一个不错的工具用于可视化分析PHP应用程序的内存使用情况的工具

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. 我知道实现此目标的唯一可信赖的方法是使用非PHP本身编写的工具进行性能分析。

Read this: 读这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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