web-dev-qa-db-fra.com

memory_get_peak_usage () avec "utilisation réelle"

Si l'argument real_usage Est défini sur true le PHP), DOCS dit qu'il obtiendra la taille réelle de la mémoire allouée par le système. S'il s'agit de false il obtiendra la mémoire signalée par emalloc()

Laquelle de ces 2 options renvoie le max. mémoire allouée par rapport à la valeur limite de la mémoire dans php.ini?

Je veux savoir à quel point le script était proche pour atteindre cette limite.

83
thelolcat

Ok, testons ceci en utilisant un script simple:

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
}

Sortie:

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

On dirait que l'utilisation réelle est la mémoire allouée par le système - qui semble être allouée dans des compartiments plus grands que ceux requis par le script. (Je suppose pour des raisons de performance). C'est aussi la mémoire utilisée par le processus php.

Le $real_usage = false usage est l'utilisation de la mémoire que vous avez réellement utilisée dans votre script, et non la quantité réelle de mémoire allouée par le gestionnaire de mémoire de Zend.

Lisez cette question pour plus d'informations.

En bref: pour vous rapprocher de la limite de mémoire, utilisez $real_usage = true

121
Niko Sams

Introduction

Vous devez utiliser memory_get_usage(false) parce que vous voulez que la mémoire soit utilisée et non allouée.

Quelle est la différence

Votre Google Mail Aurait peut-être alloué de l'espace de stockage à 25MB, Mais cela ne veut pas dire que c'est ce que vous avez utilisé pour le moment.

C’est exactement ce que disait le PHP doc

Définissez ceci sur TRUE pour obtenir la taille réelle de la mémoire allouée par le système. Si non défini ou FALSE, seule la mémoire utilisée par emalloc () est indiquée.

Les deux arguments renverraient de la mémoire allouée par rapport à la limite de mémoire, mais la différence principale est la suivante:

memory_get_usage(false) donne la mémoire utilisée par emalloc() tandis que memory_get_usage(true) renvoie un jalon pouvant être démontré ici Memory Mile Store

Je veux savoir à quelle distance le script atteignait cette limite.

Cela prendrait quelques calculs et pourrait ne fonctionner que dans des boucles ou des cas d'utilisation spécifiques. Pourquoi ai-je dit tel?

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.

Pour autant que je sache, la seule façon de vérifier la mémoire utilisée pour une section variable ou spécifique de PHP est:

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

Voir Explication , mais si vous êtes dans une fonction en boucle ou récursive, vous pouvez utiliser l'utilisation maximale de la mémoire pour estimer en toute sécurité le moment où la mémoire sera atteinte.

Exemple

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
}

sortie

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

Démo en direct

Cela peut encore échouer

Cela peut échouer car après if ($percentage > $peekPoint) {, cela ajoute quand même de faire une tâche supplémentaire avec également de la mémoire

        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.

Conclusion

Ce n'est pas une solution parfaite, mais vérifiez la mémoire à intervalle et si elle dépasse la limite (par exemple 90%) exit instantanément et quittez les options de fantaisie.

33
Baba

real_usage false indique l'utilisation de votre script tilisé. Ce sera le plus précis des deux.

real_usage true rapporte la mémoire allouée à votre script. Ce sera le plus élevé des deux.

J'utiliserais probablement true si j'essayais de comparer, car votre script ne serait jamais alloué plus que la limite de mémoire, et continuerait à s'exécuter tant qu'il (ainsi que tous les autres scripts) ne dépasserait pas cette limite. usage.

7
Glitch Desire

conformément à PHP memory_get_usage

real_usage

Définissez ce paramètre sur TRUE pour obtenir la mémoire totale allouée par le système, y compris les pages inutilisées. Si non défini ou FALSE, seule la mémoire utilisée est signalée.

donc pour obtenir la mémoire utilisée par votre script, vous devez utiliser memory_get_usage () car real_usage par défaut est false.

si vous voulez obtenir la mémoire allouée par le système sans vous soucier de la quantité réellement utilisée, utilisez memory_get_usage (true);

2
Tofeeq
<!-- Print CPU memory and load -->
<?php
$output = Shell_exec('free');
$data = substr($output,111,19);
echo $data;
echo file_get_contents('/proc/loadavg');
$load = sys_getloadavg();
$res = implode("",$load);
echo $res;
?>
0
Rahul Rohewal