跟踪PHP中的内存使用情况

Tim*_*tle 32 php memory memory-management

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

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

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

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

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

Sta*_*asM 45

real_usage 这样工作:

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

  1. 引擎从操作系统中获取多少内存("实际使用情况")
  2. 应用程序实际使用了多少内存("内部使用")

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

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

另请参阅有关此内存管理器的文章,它也有一些代码示例.

  • @MichaelCordingley,试试这个:https://web.archive.org/web/20130719064612/http://www.ibm.com/developerworks/opensource/library/os-php-v521/ (6认同)

Ali*_*xel 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, '.', '');
}
Run Code Online (Sandbox Code Playgroud)

  • 你最好使用"--pid"而不是grep,因为有一天你可能会得到一个等于你正在寻找的PID的RSS值并最终得到2行 (3认同)