php - memory_limit - memory_get_peak_usage() con "uso real"
php memory limit unlimited (4)
Si el argumento real_usage
se establece en true
los PHP DOCS dicen que obtendrá el tamaño real de la memoria asignada desde el sistema. Si es false
, recibirá la memoria informada por emalloc()
¿Cuál de estas 2 opciones devuelve el máximo? memoria asignada en relación con el valor límite de memoria en php.ini?
Quiero saber qué tan cerca estuvo el guión para llegar a ese límite.
Ok, probemos esto usando un 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
}
Salida:
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
Parece que el uso real es la memoria asignada por el sistema, que parece asignarse en segmentos más grandes que los que el script necesita actualmente. (Supongo que por razones de rendimiento). Esta es también la memoria que usa el proceso php.
El uso de $real_usage = false
es el uso de memoria que realmente $real_usage = false
en tu script, no la cantidad real de memoria asignada por el administrador de memoria de Zend.
Lee esta pregunta para más información.
En resumen: para $real_usage = true
qué tan cerca está del límite de memoria, use $real_usage = true
según PHP memory_get_usage
real_usage
Establezca esto en VERDADERO para obtener la memoria total asignada desde el sistema, incluidas las páginas no utilizadas. Si no está configurado o FALSE, solo se informa la memoria utilizada.
así que para obtener la memoria utilizada por su script, debe usar memory_get_usage () ya que el valor predeterminado de real_usage es falso.
si desea obtener la memoria asignada por el sistema, pero no le importa cuánto se usó realmente, use memory_get_usage (true);
real_usage
false informa el uso que su script usó . Este será el más preciso de los dos.
real_usage
true informa la memoria asignada a su script. Este será el más alto de los dos.
Probablemente usaría true
si intentara comparar, ya que su script nunca se asignaría más que el límite de memoria, y continuaría ejecutándose siempre que (además de todos los demás scripts) no excediera ese uso.
Introducción
Debería usar memory_get_usage(false)
porque lo que quiere es memoria utilizada, no memoria asignada.
Cual es la diferencia
Es posible que Google Mail
le haya asignado 25MB
de almacenamiento, pero eso no significa que lo haya utilizado en este momento.
Esto es exactamente lo que decía el doc. PHP
Establezca esto en VERDADERO para obtener el tamaño real de la memoria asignada desde el sistema. Si no se establece o 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)
proporciona la memoria utilizada por emalloc()
mientras memory_get_usage(true)
devuelve un hito que puede ser una demostración aquí Memory Mile Store
Quiero saber qué tan cerca estuvo el guión para llegar a ese límite.
Eso tomarí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
.
Por lo que sé, la única forma en que puedo verificar la memoria utilizada para una sección variable o 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 utilizar el uso máximo de la memoria para estimar de forma segura cuando se alcance el vistazo de la 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
}
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
Esto aún 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 revisa la memoria a intervalos y si supera la visibilidad (por ejemplo, 90%) exit
inmediato y deja las cosas elegantes