跟踪PHP中的内存使用情况

时间:2010-02-18 17:11:58

标签: php memory memory-management

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

我已经使用memory_get_usage()获得了一些积极的结果。添加real_usage标志有所帮助(不太清楚'系统'内存和'emalloc'内存之间的区别,但系统显示更大的数字)。当网址设置耗尽时,memory_get_usage()会随着网址的添加而增加。但是,我刚刚超过32M限制,我的最后一次内存检查是~18M。

每次cURL多信号请求返回时,我都会轮询内存使用情况。由于多个请求可能同时返回,因此一堆URL可能同时返回数据并实际上跳过了14M的内存使用量。但是,如果memory_get_usage()是准确的,我猜这就是发生的事情。

[更新:在我猜测之前应该运行更多测试,增加php的内存限制(但在脚本中保持'安全'数量相同)并且报告的内存使用量确实从低于我的自我限制25M到超过32M。然后,正如预期的那样,缓慢降低为未添加的URL。但我会提出这个问题:这是正确的方法吗?]

我能以这种方式信任memory_get_usage()吗?是否有更好的替代方法来获取内存(我已经看到一些脚本解析shell命令的输出)?

4 个答案:

答案 0 :(得分:45)

real_usage以这种方式工作:

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

  1. 引擎从操作系统中获取了多少内存(“实际使用情况”)
  2. 应用程序实际使用了多少内存(“内部使用”)
  3. memory_get_usage()可以返回其中任何一个。哪一个对您更有用取决于您正在研究的内容。如果您正在考虑在特定部分优化代码,“内部”可能对您更有用。如果您在全球范围内跟踪内存使用情况,那么“真实”会更有用。 memory_limit限制“实际”数字,因此只要限制允许的所有块都从系统中获取并且内存管理器无法分配请求的块,分配就会失败。请注意,在这种情况下,“内部”使用可能小于限制,但由于碎片分配仍然可能失败。

    此外,如果您使用的是某些外部存储器跟踪工具,则可以进行此设置 环境变量USE_ZEND_ALLOC=0,它将禁用上述机制并使引擎始终使用malloc()。这会有更糟糕的性能,但允许您使用malloc跟踪工具。

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

答案 1 :(得分:8)

我还假设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, '.', '');
}

答案 2 :(得分:1)

使用xdebug,因为它最近(29日1月)更新到现在包括内存分析信息。它跟踪函数调用和消耗的内存量。这使您可以非常深入地了解代码,并至少让您了解问题。

该文档很有帮助,但基本上是您,安装它可以启用性能分析xdebug.profiler_enable = 1并将输出xdebug.profiler_output_dir=/some/path提供给qcachegrind之类的工具来完成繁重的工作,让您直观地看到它

答案 3 :(得分:-5)

我的PHP脚本从来没有真正出现过内存问题,所以我认为找不到问题的原因并不是很有帮助,但我可以推荐的是你得到一个PHP加速器,你会注意到严重的性能提升和内存使用量下降。这是一个加速器列表和一篇比较其中几个的文章(性能比其中任何一个好3倍)

Wikipedia List

Benchmark

基准测试已有2年的历史,但您可以了解性能的提升。

如果必须,如果你在使用加速器时仍然遇到问题,你也可以增加PHP的内存限制。打开你的php.ini并找到:

memory_limit = 32M;

然后稍微增加一点。