memory_get_peak_usage()与“真实用法”

如果real_usage参数设置为true那么PHP DOCS会说将从系统中获得分配的实际内存大小。 如果它是false它会得到由emalloc()报告的内存

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

我想知道剧本到底有多接近。

好的,让我们用一个简单的脚本来testing它:

 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 } 

输出:

 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 

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

$real_usage = false用法是您在脚本中实际使用的内存使用情况,而不是由Zend的内存pipe理器分配的实际内存量。

阅读这个问题了解更多信息。

简而言之:要获得内存限制,请使用$real_usage = true

介绍

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

有什么不同

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

这正是PHP文档所说的

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

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

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

我想知道剧本到底有多接近。

这将需要一些math,可能只能在循环或特定的用例。 我为什么这么说?

想像

 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

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

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

请参阅说明 ,但是如果您处于循环或recursion函数中,则可以使用最大的内存使用情况来安全地估计何时会达到内存窥视。

 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 } 

产量

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

现场演示

这可能仍然失败

它可能会失败,因为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.

结论

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

real_usage false报告您的脚本使用的用法。 这将是两个更准确的。

real_usage true报告分配给脚本的内存。 这将是两者中较高的。

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

根据PHP memory_get_usage

real_usage

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

所以要得到你的脚本使用的内存,你应该使用memory_get_usage()作为默认的real_usage是false。

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