Introducción
Debe usar memory_get_usage(false)
porque lo que quiere es memoria usada, no memoria asignada.
Cual es la diferencia
Tu Google Mail
podrías haber asignado25MB
espacio de almacenamiento para usted, pero eso no significa que sea lo que ha utilizado en este momento.
Esto es exactamente lo que decía el documento PHP
Establezca esto en TRUE para obtener el tamaño real de la memoria asignada desde el sistema. Si no se establece o es FALSE, solo se informa la memoria utilizada por emalloc ().
Ambos argumentos devolverían la memoria asignada en relación con el límite de memoria, pero la principal diferencia es:
memory_get_usage(false)
dar la memoria utilizada por emalloc()
mientras memory_get_usage(true)
devuelve el hito que se puede demostrar aquí Memory Mile Store
Quiero saber qué tan cerca estuvo el guión de alcanzar ese límite.
Eso requeriría algunas matemáticas y podría funcionar solo en bucles o casos de uso específicos. ¿Por qué dije eso?
Imagina
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
.
Hasta donde yo sé, la única forma en que puedo verificar la memoria utilizada para una variable o sección específica de PHP es:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
Consulte la Explicación , pero si está en un bucle o en una función recursiva, puede usar el uso máximo de memoria para estimar de manera segura cuándo se alcanzaría el punto máximo de memoria.
Ejemplo
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
}
Salida
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
Demo en vivo
Esto todavía puede fallar
Puede fallar porque después de if ($percentage > $peekPoint) {
esto todavía se agrega para hacer una tarea adicional con también consume memoria
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.
Conclusión
No es una solución perfecta, pero verifique la memoria a intervalos y si excede la vista (por ejemplo, 90%) al exit
instante y deje las cosas elegantes