104 votes

memory_get_peak_usage () avec "utilisation réelle"

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

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

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

156voto

Niko Sams Points 2286

Ok, permet de tester ce à l'aide d'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
}

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

Semble réel l'utilisation de la mémoire est allouée à partir du système - qui semble avoir affecté dans des grands seaux que nous avons actuellement besoin de par le script. (Je suppose que pour des raisons de performances). C'est aussi la mémoire du processus php utilise.

L' $real_usage = false d'utilisation est l'utilisation de la mémoire vous sont effectivement utilisés dans votre script. Et comme on peut le voir qui est utilisé par memory_limit.

Lire cette question pour plus d'informations.

En bref: pour obtenir quelle distance êtes-vous à la limite de la mémoire, utilisez $real_usage = false

43voto

Baba Points 49157

Introduction

Vous devez utiliser memory_get_usage(false) parce que ce que vous voulez, c'est la mémoire utilisée pas la mémoire allouée.

Quel est la Différence

Votre Google Mail pourrait avoir affecté 25MB de stockage pour vous, mais cela ne signifie pas qu'est ce que vous avez utilisée à l'heure actuelle.

C'est exactement ce que le PHP doc a dit

Activez cette option pour obtenir la taille réelle de la mémoire allouée à partir du système. Si pas de définir ou de FAUX seulement la mémoire utilisée par les appels à emalloc() est signalé.

Fois argument est le retour de la mémoire allouée par rapport à la limite de la mémoire, mais la principale différence est:

memory_get_usage(false) donner de la mémoire utilisée par emalloc() tout memory_get_usage(true) retours étape qui peut être de démonstration ici la Mémoire du Mile Magasin

Je veux savoir comment le script de frapper cette limite.

Ce serait prendre un certain maths et peut ne fonctionner que dans des boucles ou des cas d'utilisation spécifiques. Pourquoi ai-je dis ?

Imaginez

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.

Autant que je sache, la seule façon que je puisse vérifier la mémoire utilisée pour une variable ou d'une section 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 boucle ou d'une fonction récursive, vous pouvez utiliser au maximum l'utilisation de la mémoire pour estimer en toute sécurité lorsque la mémoire de peek serait atteint.

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émonstration En Direct

Cela peut encore échouer

Il peut échouer parce qu'après l' if ($percentage > $peekPoint) { - ce encore encore ajouter à effectuer d'autres tâches avec aussi consomme 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érifier pour la mémoire à intervalle et si sa dépasse peek (par exemple, 90%) exit instantanément et de laisser la fantaisie

8voto

Alula Errorpone Points 6304

real_usage false indique l'utilisation que votre script a utilisée . Ce sera le plus précis des deux.

real_usage true indique 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 (plus tous les autres scripts) ne dépasserait pas cet usage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X