memory_peak_get_usage(false)在PHP中真正做了什么?

时间:2017-05-31 18:20:53

标签: php memory memory-management

我想我已经在stackoverflow.com上阅读了有关memory_get_usage()和memory_peak_get_usage()函数的所有主题,但似乎这些解释不适合我的情况。

我的脚本显示以下结果:

memory peak usage (true): 2
memory peak usage (false): 0.44921112060547
memory get usage: 0.40422821044922

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2414016723633

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2413940429688

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2425689697266

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2467498779297

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.5322036743164

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.5322113037109

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.406005859375

日志由以下命令生成,有时通过代码重复:

echo 'memory peak usage (true): '.(memory_get_peak_usage(true)/1024/1024).'<br>';
echo 'memory peak usage (false): '.(memory_get_peak_usage(false)/1024/1024).'<br>';
echo 'memory get usage: '.(memory_get_usage()/1024/1024).'<br><br>';

信息:对于最后一个日志,我将一些变量设置为null,我认为它们被垃圾收集器释放,因为内存的使用率从2.53降低到2.40。

我的问题是: WTH正在发生?为什么memory_get_usage()大于memory_get_peak_usage(true)?为什么memory_get_peak_usage(false)大于memory_get_peak_usage(true)?

它完全不同于这个帖子: memory_get_peak_usage() with "real usage"

1 个答案:

答案 0 :(得分:0)

首先,这个页面http://jpauli.github.io/2014/07/02/php-memory.html,详细解释了PHP如何分配内存,以及ZendMM如何工作。如果您愿意参与低级PHP编程,我强烈建议您查看。

现在,继续讨论你的问题,让我告诉你:互联网上没有找到满意的答案。话虽如此,接下来是基于文档和其他信息来源的公平假设的结果。

如PHP的文档中所述, memory_get_usage (默认$ real_usage为false)返回分配给脚本的当前内存量。它还只跟踪使用emalloc()分配的内存。

在进一步推进之前,让我们先给出一些定义:

  • memory_get_usage(false) - 返回调用emalloc +头字节+内存对齐所请求的字节总和。它并不完美,因为它没有考虑到由于无法在分配的块的剩余部分中容纳空间而浪费的块数量。

  • memory_get_peak_usage(false) - 返回已分配给脚本的内存峰值。与上面的情况相同,它可能会给出比实际使用的字节数更低的结果。

  • memory_get_peak_usage(true) - 返回脚本分配的实际字节峰值。

&#34;为什么memory_get_usage()大于memory_get_peak_usage(true)?&#34;

最有可能发生这种情况,因为他们正在使用不同的方式来计算内存使用量。 - 峰值使用率(true)试图告诉您脚本达到的实际字节数,而get_usage(false)仅告诉您所有emalloc调用总和的数量。它可能更高,因为它没有被编程来实现你的程序当前正在释放内存,并且说由于不断释放和分配,2.5字节的数据实际上可能实际上适合整个时间的实际内存的2个字节。 。 这基于我在上面链接的页面中所做的评论:

  

memory_get_usage()提供平均信息,通常是准确的,但在字节基础上不是100%准确

意思是它试图告诉你它所相信的平均金额&#39;通过计算emallocs进行分配,但只要它被设置为false,它就无法知道你的脚本花费了多少内存块。

为什么memory_get_peak_usage(false)大于Memory_get_peak_usage(true)?&#34;

这是它变得奇怪的部分。我以前从未见过,并且相信这很可能是一种误解。这可能是因为您的脚本以(错误)实现认为内存仍然分配给该资源的方式分配内存,实际上,(true)确保您的脚本使用的最多是2个字节

我没有使用PHP的核心经验,并尝试通过Google搜索来回答这个问题。我希望它可以帮助您了解正在发生的事情。

在任何情况下,即使它没有完美的意义,尽量不要在愤怒中猛击你的键盘。 &#34; false&#34;这些方法的实施非常不稳定,不应该用来与他们的&#34; true&#34;进行比较。同行。最糟糕的情况是,这只是PHP部分的糟糕实现。

祝你的PHP冒险好运!

<强>更新

这对我没什么帮助,但我确实找到了这两个函数的源代码:

这里是:

ZEND_API size_t zend_memory_usage(int real_usage)
{
#if ZEND_MM_STAT
    if (real_usage) {
        return AG(mm_heap)->real_size;
    } else {
        size_t usage = AG(mm_heap)->size;
        return usage;
    }
#endif
    return 0;
}

ZEND_API size_t zend_memory_peak_usage(int real_usage)
{
#if ZEND_MM_STAT
    if (real_usage) {
        return AG(mm_heap)->real_peak;
    } else {
        return AG(mm_heap)->peak;
    }
#endif
    return 0;
}

<强>参考

memory_get_peak_usage documentation

memory_get_usage documentation

Perfect script for calculating memory usage