代码之家  ›  专栏  ›  技术社区  ›  The Pixel Developer

跟踪方法的内存使用情况

  •  10
  • The Pixel Developer  · 技术社区  · 14 年前

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

    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 回复  |  直到 12 年前
        1
  •  5
  •   Kendall Hopkins    14 年前

    你可以用 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
            )
    )
    

    可能的问题

    由于这个profiler类将数据存储在PHP中,因此总体内存使用量将人为增加。避免这个问题的一种方法是在运行时将数据写入文件(序列化),完成后可以将其读回。

        2
  •  2
  •   Mark Baker    14 年前

    这个 XHProfLive Facebook开发人员开发的profiler提供了这种程度的函数/方法级别的分析,可以作为 PECL download .

        3
  •  1
  •   Utku Zihnioglu    14 年前

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

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

        4
  •  0
  •   Yeroon    14 年前

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

    你这样做的结果是什么:

    $s = memory_get_usage();
    
    $class->hello('a');
    
    echo memory_get_peak_usage() - $s;
    
        5
  •  0
  •   Community CDub    8 年前

    您应该使用php内存工具。

    有一个很好的发现,在这个如此线程: Tools to visually analyze memory usage of a PHP app

    this other question 对你的问题有更多的答案

        6
  •  0
  •   Alfonso de la Osa    14 年前

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

    请阅读:

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