跟踪方法的内存使用情况 [英] Track memory usage of a method

查看:124
本文介绍了跟踪方法的内存使用情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还没有找到一个优雅的解决方案。

 类示例
我有一个带有方法的类,我想跟踪内存使用情况而不修改该函数。 {
public function hello($ name)
{
$ something = str_repeat($ name,pow(1024,2));
}
}

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

所以任务是,多少内存不会有 hello()在不干涉它的情况下使用?



注意:此方法的内存使用量应为1MB。我尝试用 memory_get_usage(); 来打包调用无效:

 <$ c 

$ {
$ b $ {
$($ name,pow(1024,2));
}
}

$ class = new示例;

$ s = memory_get_usage();

$ class-> hello('a');

echo memory_get_usage() - $ s;

这只会导致 144 字节正确的)。我已经通过使用 ReflectionMethod 类尝试了各种各样的Reflection。



我有一种感觉,我需要do是计算方法中的差异:(如果有人能想到更清洁的东西,那么你真的会让我的一天。

编辑:我应该提到这是基准测试应用程序的背景,所以尽管 memory_get_peak_usage 的作用在于它正确地返回了内存使用情况,但它也会歪曲高内存方法,现在如果有重置内存统计信息的方法,那也可以。

解决方案

您可以使用 register_tick_function ,然后转储每一个tick(行)并且稍后分析 memeory_get_usage ,可以使用 debug_backtrace 查找行号关系使用 microtime



Profiler类

  class Profiler 
{

private $ _data_array = array();
$ b $ function __construct()
{
register_tick_function(array($ this,tick));
declare(ticks = 1);


函数__destruct()
{
unregister_tick_function(array($ this,tick));

$ b $函数tick()
{
$ this-> _data_array [] = array(
memory=> memory_get_usage() ,
time=> microtime(TRUE),
//如果您需要回溯,您可以取消注释下一行
//backtrace=> debug_backtrace(FALSE),
);
}

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

示例

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

$ profiler = new Profiler(); //创建时开始记录

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

$ data_array = $ profiler-> getDataArray();

unset($ profiler); //当__destruct被调用时停止记录

print_r($ data_array);

输出

< $(
[memory] ​​=> 638088
[time] => 1290788749.72

[1] =>数组(
[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] =>数组(
[memory] ​​=> 641664
[time] => 1290788749.72


可能的问题



由于此剖析器类将数据存储在PHP中,整个内存使用量将会人为增加。避免这个问题的一种方法是在你去(序列化)时将数据写出到文件中,当你完成后,你可以读回数据。


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.

这篇关于跟踪方法的内存使用情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆