繁体   English   中英

跟踪方法的内存使用情况

[英]Track memory usage of a method

我还没有找到一个优雅的解决方案。 我有一个带有要跟踪的内存使用情况而无需修改函数的方法的类:

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

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

因此,任务是, hello()在不干涉的情况下使用了多少内存?

注意:此方法的内存使用量应为1MB。 我试过用memory_get_usage();包装该调用memory_get_usage(); 无济于事:

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;

这只会导致144个字节(完全不正确)。 我已经通过使用ReflectionMethod类使用了ReflectionMethod尝试了各种魔术。

我有一种感觉,我需要做的是计算方法中的差异:(.。如果有人可以想到任何更清洁的方法,那么您真的会过得很愉快。

编辑:我应该提到这是在基准测试应用程序的上下文中。 因此,虽然memory_get_peak_usage在正确返回内存使用量的意义上起作用,但它也会在高内存方法后偏向运行基准测试。 现在,如果有一种方法可以重置内存统计信息,那也可能很好。

您可以使用register_tick_function并仅将memeory_get_usage转储出每个刻度(行)并在以后进行分析。 通过使用debug_backtrace查找与内存使用相关的行号或使用microtime增加每行的时间,可以改进以下类。

探查器类

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

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

输出量

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

可能的问题

由于此事件探查器类将数据存储在PHP中,因此总的内存使用量将人为增加。 避免此问题的一种方法是在进行数据处理(序列化)时将数据写到文件中,完成后可以将其读回。

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

从函数返回时,内存被释放。

您可以添加$s = memory_get_usage(); ... echo memory_get_usage() - $s; $s = memory_get_usage(); ... echo memory_get_usage() - $s; 阻止功能内部。 这样,将不会释放所使用的内存。

在hello()调用结束后,它似乎已经“释放”了内存。

这样做的结果是什么:

$s = memory_get_usage();

$class->hello('a');

echo memory_get_peak_usage() - $s;

您应该使用php记忆工具。

在该SO线程中可以找到一个不错的工具用于可视化分析PHP应用程序的内存使用情况的工具

这另一个问题对您的问题还有其他一些答案

我知道实现此目标的唯一可信赖的方法是使用非PHP本身编写的工具进行性能分析。

读这个:

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

暂无
暂无

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

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