Introdução
Você deve usar memory_get_usage(false)
porque o que você quer é a memória usada, não a memória alocada.
Qual é a diferença
Você Google Mail
pode ter alocado 25MB
espaço de armazenamento para você, mas isso não significa que é o que você está usando no momento.
Isso é exatamente o que o documento PHP estava dizendo
Defina como TRUE para obter o tamanho real da memória alocada do sistema. Se não for definido ou FALSE, apenas a memória usada por emalloc () é relatada.
Ambos os argumentos retornariam memória alocada em relação ao limite de memória, mas a principal diferença é:
memory_get_usage(false)
fornece a memória usada por emalloc()
while memory_get_usage(true)
retorna o marco que pode ser demonstrado aqui Memory Mile Store
Quero saber o quão perto esteve o script de atingir esse limite.
Isso exigiria alguma matemática e só funcionaria em loops ou casos de uso específicos. Por que eu disse isso?
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
.
Pelo que eu sei, a única maneira de verificar a memória usada para uma variável ou seção específica do PHP é:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
Consulte a Explicação , mas se você estiver em um loop ou em uma função recursiva, poderá usar o uso máximo de memória para estimar com segurança quando o pico de memória será alcançado.
Exemplo
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
}
Resultado
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
Demonstração ao vivo
Isso ainda pode falhar
Pode falhar porque depois if ($percentage > $peekPoint) {
disso ainda adicionar tarefas adicionais com também consome memória
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.
Conclusão
Não é uma solução perfeita, mas verifique se há memória no intervalo e se ela exceder peek (por exemplo, 90%) exit
instantaneamente e deixe as coisas sofisticadas