代码之家  ›  专栏  ›  技术社区  ›  Tim Lytle

在PHP中跟踪内存使用情况

  •  31
  • Tim Lytle  · 技术社区  · 15 年前

    我试图跟踪处理URL的脚本的内存使用情况。基本思想是在向curl多处理程序添加另一个url之前检查是否有一个合理的缓冲区。我使用的是一个“滚动卷曲”的概念,在多处理程序运行时处理URL数据。这意味着我可以通过每次处理和删除现有的URL时从池中添加新的URL来保持N个连接的活动状态。

    我用过 memory_get_usage() 有一些积极的结果。添加 real_usage 标记有帮助(对“系统”内存和“Emalloc”内存之间的区别不太清楚,但系统显示的数字更大)。 内存获取使用()。 当URL被添加时是否上升,当URL集被耗尽时是否下降。但是,我刚刚超过了32米的限制,我最后的记忆检查是~18米。

    每次curl多信号请求返回时,我都会轮询内存使用情况。由于多个请求可能同时返回,因此有可能许多URL同时返回数据,并实际增加了14m的内存使用量。 内存获取使用()。 是准确的,我想是这样的。

    [ 更新 :应该在询问我之前运行更多的测试,增加了php的内存限制(但在脚本中保留了相同的“安全”量),并且报告的内存使用量确实从我自己设定的25米的限制以下跃升到了32米以上。然后,正如预期的那样,在没有添加URL的地方,缓慢地向下倾斜。但我还是不提这个问题:这是正确的方法吗?]

    我能信任吗 内存获取使用()。 这样?是否有更好的方法来获取内存使用(我见过一些脚本解析shell命令的输出)?

    4 回复  |  直到 7 年前
        1
  •  44
  •   Buttle Butkus    11 年前

    real_usage 这样工作:

    Zend的内存管理器不为它需要的每个块使用系统malloc。相反,它分配了一大块系统内存(增量为256K,可以通过设置环境变量来更改 ZEND_MM_SEG_SIZE )内部管理。因此,内存使用有两种:

    1. 引擎从操作系统中占用了多少内存(“实际使用”)。
    2. 应用程序实际使用了多少内存(“内部使用”)。

    其中任何一个都可以通过 memory_get_usage() . 哪个对你更有用取决于你在调查什么。如果您想在特定部分优化代码,“内部”可能对您更有用。如果您在全球范围内跟踪内存使用情况,“real”会更有用。 memory_limit 限制“实数”,因此只要从系统中取出限制允许的所有块,并且内存管理器无法分配请求的块,分配就会失败。请注意,在这种情况下,“内部”用法可能小于限制,但由于碎片化,分配仍然可能失败。

    另外,如果您使用一些外部内存跟踪工具,则可以设置 环境变量 USE_ZEND_ALLOC=0 这将使上述机构失效,使发动机始终使用 malloc() . 这将有更糟糕的性能,但允许您使用malloc跟踪工具。

    另请参见 an article about this memory manager 它也有一些代码示例。

        2
  •  8
  •   Alix Axel    15 年前

    我也假设 memory_get_usage() 是安全的,但我想您可以比较这两种方法并自己决定,下面是一个解析系统调用的函数:

    function Memory_Usage($decimals = 2)
    {
        $result = 0;
    
        if (function_exists('memory_get_usage'))
        {
            $result = memory_get_usage() / 1024;
        }
    
        else
        {
            if (function_exists('exec'))
            {
                $output = array();
    
                if (substr(strtoupper(PHP_OS), 0, 3) == 'WIN')
                {
                    exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output);
    
                    $result = preg_replace('/[\D]/', '', $output[5]);
                }
    
                else
                {
                    exec('ps -eo%mem,rss,pid | grep ' . getmypid(), $output);
    
                    $output = explode('  ', $output[0]);
    
                    $result = $output[1];
                }
            }
        }
    
        return number_format(intval($result) / 1024, $decimals, '.', '');
    }
    
        3
  •  1
  •   SeanDowney    7 年前

    使用 xdebug ,正如最近(1月29日)更新到现在包含内存分析信息。它跟踪函数调用及其占用的内存量。这可以让您对代码有非常深入的了解,至少可以让您了解问题的方向。

    文档是有帮助的,但本质上您可以安装它来启用分析 xdebug.profiler_enable = 1 并给出输出 xdebug.profiler_output_dir=/some/path 到一个工具,如 qcachegrind 进行重物提升,让人从视觉上看到它。

        4
  •  -5
  •   Dr Hydralisk    15 年前

    嗯,我的PHP脚本从来没有出现过内存问题,所以我认为我不能帮你找到问题的原因,但是我建议你使用一个PHP加速器,你会注意到性能的严重提高和内存使用率的下降。下面是一个加速器列表和一篇文章,比较其中的一些加速器(性能比任何加速器都好3倍)

    Wikipedia List

    Benchmark

    基准是2年前的,但您可以了解到性能的提高。

    如果必须这样做,即使在使用加速器时仍然有问题,也可以在PHP中增加内存限制。打开php.ini并找到:

    memory_limit = 32M;
    

    只需稍微增加一点。