php memory_get_peak_usage() 与“实际使用”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15745385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:52:41  来源:igfitidea点击:

memory_get_peak_usage() with "real usage"

phpmemorymemory-management

提问by thelolcat

If the real_usageargument is set to truethe PHP DOCS say it will get the real size of memory allocated from system. If it's falseit will get the memory reported by emalloc()

如果real_usage参数设置为truePHP DOCS,则表示它将获得系统分配的实际内存大小。如果是,false它会得到内存报告emalloc()

Which one of these 2 options returns the max. memory allocated relative to the memory limit value in php.ini ?

这两个选项中的哪一个返回最大值。相对于 php.ini 中的内存限制值分配的内存?

I want to know how close was the script to hit that limit.

我想知道脚本离达到该限制有多近。

回答by Niko Sams

Ok, lets test this using a simple script:

好的,让我们使用一个简单的脚本来测试一下:

ini_set('memory_limit', '1M');
$x = '';
while(true) {
  echo "not real: ".(memory_get_peak_usage(false)/1024/1024)." MiB\n";
  echo "real: ".(memory_get_peak_usage(true)/1024/1024)." MiB\n\n";
  $x .= str_repeat(' ', 1024*25); //store 25kb more to string
}

Output:

输出:

not real: 0.73469543457031 MiB
real: 0.75 MiB

not real: 0.75910949707031 MiB
real: 1 MiB

...

not real: 0.95442199707031 MiB
real: 1 MiB

not real: 0.97883605957031 MiB
real: 1 MiB

PHP Fatal error:  Allowed memory size of 1048576 bytes exhausted (tried to allocate 793601 bytes) in /home/niko/test.php on line 7

Seems like real usage is the memory allocated from the system - which seems to get allocated in larger buckets than currently needed by the script. (I guess for performance reasons). This is also the memory the php process uses.

似乎真正的使用是从系统分配的内存 - 这似乎是在比脚本当前所需的更大的存储桶中分配的。(我猜是出于性能原因)。这也是php进程使用的内存。

The $real_usage = falseusage is the memory usage you actually used in your script, not the actual amount of memory allocated by Zend's memory manager.

$real_usage = false用法是,你实际上是在你的脚本中使用的内存使用情况,而不是由Zend的内存管理器分配的内存的实际金额。

Read this questionfor more information.

阅读此问题以获取更多信息。

In short: to get how close are you to the memory limit, use $real_usage = true

简而言之:要了解您离内存限制有多近,请使用 $real_usage = true

回答by Baba

Introduction

介绍

You should use memory_get_usage(false)because what you want is memory used not memory allocated.

您应该使用,memory_get_usage(false)因为您想要的是使用的内存而不是分配的内存。

Whats the Difference

有什么不同

Your Google Mailmight have allocated 25MBof storage for you but it does not mean that is what you have used at the moment.

Google Mail可能已经25MB为您分配了存储空间,但这并不意味着这是您目前使用的空间。

This is exactly what the PHP doc was saying

这正是 PHP 文档所说的

Set this to TRUE to get the real size of memory allocated from system. If not set or FALSE only the memory used by emalloc() is reported.

将此设置为 TRUE 以获取系统分配的实际内存大小。如果未设置或 FALSE,则仅报告 emalloc() 使用的内存。

Both argument would return memory allocated relative to the memory limit but the main difference is:

这两个参数都将返回相对于内存限制分配的内存,但主要区别是:

memory_get_usage(false)give the memory used by emalloc()while memory_get_usage(true)returns milestone which can be demonstration here Memory Mile Store

memory_get_usage(false)给出emalloc()while使用的内存memory_get_usage(true)返回里程碑,可以在这里演示Memory Mile Store

I want to know how close was the script to hit that limit.

我想知道脚本离达到该限制有多近。

That would take some maths and might only work in loops or specific use cases. Why did i say such ?

这需要一些数学运算,并且可能仅适用于循环或特定用例。我为什么这么说?

Imagine

想象

ini_set('memory_limit', '1M');
$data = str_repeat(' ', 1024 * 1024);

The above script would fail before you even get the chance to start start checking memory.

The above script would fail before you even get the chance to start start checking memory.

As far as i know the only way i can check memory used for a variable or specific section of PHP is:

据我所知,我可以检查用于 PHP 变量或特定部分的内存的唯一方法是:

$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;

See Explanation, but if you are in a loop or recursive function you can use maximum memory usage to estimate safely when memory peek would be reached.

请参阅说明,但如果您处于循环或递归函数中,您可以使用最大内存使用量来安全地估计何时达到内存峰值。

Example

例子

ini_set('memory_limit', '1M');

$memoryAvailable = filter_var(ini_get("memory_limit"), FILTER_SANITIZE_NUMBER_INT);
$memoryAvailable = $memoryAvailable * 1024 * 1024;

$peekPoint = 90; // 90%

$memoryStart = memory_get_peak_usage(false);
$memoryDiff = 0;

// Some stats
$stat = array(
        "HIGHEST_MEMORY" => 0,
        "HIGHEST_DIFF" => 0,
        "PERCENTAGE_BREAK" => 0,
        "AVERAGE" => array(),
        "LOOPS" => 0
);

$data = "";
$i = 0;
while ( true ) {
    $i ++;

    // Get used memory
    $memoryUsed = memory_get_peak_usage(false);

    // Get Diffrence
    $memoryDiff = $memoryUsed - $memoryStart;

    // Start memory Usage again
    $memoryStart = memory_get_peak_usage(false);

    // Gather some stats
    $stat['HIGHEST_MEMORY'] = $memoryUsed > $stat['HIGHEST_MEMORY'] ? $memoryUsed : $stat['HIGHEST_MEMORY'];
    $stat['HIGHEST_DIFF'] = $memoryDiff > $stat['HIGHEST_DIFF'] ? $memoryDiff : $stat['HIGHEST_DIFF'];
    $stat['AVERAGE'][] = $memoryDiff;
    $stat['LOOPS'] ++;
    $percentage = (($memoryUsed + $stat['HIGHEST_DIFF']) / $memoryAvailable) * 100;

    // var_dump($percentage, $memoryDiff);

    // Stop your scipt
    if ($percentage > $peekPoint) {

        print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
        $stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
        $stat = array_map(function ($v) {
            return sprintf("%0.2f", $v / (1024 * 1024));
        }, $stat);
        $stat['LOOPS'] = $i;
        $stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
        echo json_encode($stat, 128);
        break;
    }

    $data .= str_repeat(' ', 1024 * 25); // 1kb every time
}

Output

输出

Stoped at: 95.86%
{
    "HIGHEST_MEMORY": "0.71",
    "HIGHEST_DIFF": "0.24",
    "PERCENTAGE_BREAK": "95.86%",
    "AVERAGE": "0.04",
    "LOOPS": 11
}

Live Demo

现场演示

This may still fail

这可能仍然失败

It may fail because after if ($percentage > $peekPoint) {this still still add to do additional task with also consumes memory

它可能会失败,因为在if ($percentage > $peekPoint) {此之后仍然添加做额外的任务也消耗内存

        print(sprintf("Stoped at: %0.2f", $percentage) . "%\n");
        $stat['AVERAGE'] = array_sum($stat['AVERAGE']) / count($stat['AVERAGE']);
        $stat = array_map(function ($v) {
            return sprintf("%0.2f", $v / (1024 * 1024));
        }, $stat);
        $stat['LOOPS'] = $i;
        $stat['PERCENTAGE_BREAK'] = sprintf("%0.2f", $percentage) . "%";
        echo json_encode($stat, 128);
        break;

If the memory to process this request is grater than the memory available the script would fail.

If the memory to process this request is grater than the memory available the script would fail.

Conclusion

结论

Its not a perfect solution but check for memory at interval and if its exceed peek (eg 90%) exitinstantly and leave the fancy stuff

它不是一个完美的解决方案,但每隔一段时间检查内存,如果它立即超过 peek(例如 90%) exit并留下花哨的东西

回答by Glitch Desire

real_usagefalse reports the usage your script used. This will be the more accurate of the two.

real_usagefalse 报告您的脚本使用的用法。这将是两者中更准确的一个。

real_usagetrue reports the memory allocatedto your script. This will be the higher of the two.

real_usagetrue 报告分配给脚本的内存。这将是两者中较高的一个。

I'd probably use trueif I was trying to compare, as your script would never be allocated more than memory limit, and would continue to run as long as it (plus all other scripts) didn't exceed that usage.

true如果我试图比较,我可能会使用,因为您的脚本永远不会分配超过内存限制,并且只要它(加上所有其他脚本)不超过该使用量,就会继续运行。

回答by Tofeeq

as per PHP memory_get_usage

根据 PHP memory_get_usage

real_usage

Set this to TRUE to get total memory allocated from system, including unused pages. If not set or FALSE only the used memory is reported.

real_usage

将此设置为 TRUE 以获取从系统分配的总内存,包括未使用的页面。如果未设置或 FALSE,则仅报告使用的内存。

so to get the memory used by your script you should use memory_get_usage() as default real_usage is false.

因此,要获取脚本使用的内存,您应该使用 memory_get_usage() 作为默认 real_usage 为 false。

if you want to get the memory allocated by the system but don't care how much was actually used, use memory_get_usage(true);

如果你想获取系统分配的内存但不关心实际使用了多少,使用 memory_get_usage(true);

回答by Rahul Rohewal

<!-- Print CPU memory and load -->
<?php
$output = shell_exec('free');
$data = substr($output,111,19);
echo $data;
echo file_get_contents('/proc/loadavg');
$load = sys_getloadavg();
$res = implode("",$load);
echo $res;
?>