跟踪方法的内存使用情况

时间:2010-11-26 14:42:08

标签: php function memory methods

我还没有找到一个优雅的解决方案。我有一个类,我希望在不修改函数的情况下跟踪内存使用情况:

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

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

所以任务是hello()使用多少内存而不干扰它?

注意:此方法的内存使用量应为1MB。我尝试用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类尝试了各种魔法。

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

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

6 个答案:

答案 0 :(得分:5)

您可以使用register_tick_function并在每个tick(行)中转储memeory_get_usage并稍后进行分析。通过使用debug_backtrace查找与内存使用情况相关的行号或使用microtime添加每行时间,可以改进以下类别。

Profiler类

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中,因此总体内存使用量将人为增加。避免这个问题的一种方法是将数据写入文件(序列化),完成后可以将其读回。

答案 1 :(得分:2)

由Facebook人员开发的XHProfLive分析器提供了这种程度的功能/方法级分析,并以PECL download形式提供。

答案 2 :(得分:1)

从函数返回时释放内存。

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

答案 3 :(得分:0)

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

执行此操作后会有什么结果:

$s = memory_get_usage();

$class->hello('a');

echo memory_get_peak_usage() - $s;

答案 4 :(得分:0)

你应该使用php内存工具。

在这个SO线程中有一个很好的: Tools to visually analyze memory usage of a PHP app

this other question对您的问题提供了一些进一步的答案

答案 5 :(得分:0)

我知道实现这一目标的唯一可靠方法是使用不是用PHP本身编写的工具进行分析。

阅读本文:

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