Pregunta memory_get_peak_usage () con "uso real"


Si el real_usage argumento está configurado para true los PHP DOCS dicen que obtendrá el tamaño real de la memoria asignada desde el sistema. Si es false obtendrá 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.


75
2018-04-01 14:32


origen


Respuestas:


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.

los $real_usage = false el uso es el uso de memoria que realmente usaste en tu script, no la cantidad real de memoria asignada por el administrador de memoria de Zend.

Leer esta pregunta para más información.

En resumen: para saber qué tan cerca está usted del límite de memoria, use $real_usage = true


105
2018-04-26 14:53



Introducción 

Deberías usar memory_get_usage(false) porque lo que quiere es memoria utilizada, no memoria asignada.

Cual es la diferencia 

Tu Google Mail podría haber asignado 25MB de almacenamiento para usted, pero eso no significa que es lo que ha 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) dar la memoria utilizada por emalloc() mientras memory_get_usage(true) devuelve un hito que puede ser una demostración aquí Tienda Memory Mile

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;

Ver explicación, pero si está en un bucle o en una función recursiva, puede utilizar el uso máximo de memoria para estimar de forma segura cuando se alcance la posibilidad de que se visualice 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
}

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 aún puede fallar

Puede fallar porque después 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 verifica la memoria a intervalos y si es superior (por ejemplo, 90%) exit al instante y dejar las cosas de lujo


29
2018-04-26 20:51



real_usage falso informa el uso de su secuencia de comandos usado. Este será el más preciso de los dos.

real_usage verdadero informa la memoria asignado a tu script Este será el más alto de los dos.

Probablemente usaría true si intentara comparar, ya que su secuencia de comandos nunca se asignaría más que el límite de memoria, y continuaría ejecutándose mientras no excediera ese uso (más todos los demás scripts).


7
2018-04-26 13:57



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);


1
2017-11-01 13:02