Frage memory_get_peak_usage () mit "echter Nutzung"


Wenn die real_usage Argument ist auf gesetzt true die PHP-DOCS sagen, dass es die reale Größe des Speichers erhält, der vom System zugeteilt wird. Wenn es false es wird den Speicher erhalten, von dem berichtet wird emalloc()

Welche der beiden Optionen gibt die max. Speicher zugeordnet in Bezug auf den Speichergrenzwert in php.ini?

Ich möchte wissen, wie nah das Skript war, um dieses Limit zu erreichen.


75
2018-04-01 14:32


Ursprung


Antworten:


Ok, lass uns das mit einem einfachen Skript testen:

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
}

Ausgabe:

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

Scheinbar ist die tatsächliche Nutzung der Speicher, der vom System zugewiesen wird - der in größeren Buckets zugewiesen wird, als das Script momentan benötigt. (Ich denke aus Leistungsgründen). Dies ist auch der Speicher, den der PHP-Prozess verwendet.

Das $real_usage = false Verwendung ist die Speichernutzung, die Sie tatsächlich in Ihrem Skript verwendet haben, nicht die tatsächliche Speichermenge, die von Zends Speichermanager zugewiesen wurde.

Lesen diese Frage für mehr Informationen.

Kurz gesagt: Um zu sehen, wie nahe Sie dem Speicherlimit sind, verwenden Sie $real_usage = true


105
2018-04-26 14:53



Einführung 

Du solltest benutzen memory_get_usage(false) weil, was Sie wollen, ist Speicher verwendet nicht Speicher zugewiesen.

Was ist der Unterschied 

Ihre Google Mail könnte zugeteilt haben 25MB Speicher für dich, aber es bedeutet nicht, dass du das im Moment benutzt hast.

Das ist genau das, was das PHP-Dokument gesagt hat

Setzen Sie dies auf TRUE, um die tatsächliche Speichergröße zu erhalten, die vom System zugewiesen wurde. Wenn nicht gesetzt oder FALSE, wird nur der von emalloc () verwendete Speicher gemeldet.

Beide Argumente würden Speicher zugewiesen, der relativ zum Speicherlimit zugewiesen wurde, aber der Hauptunterschied ist:

memory_get_usage(false) gib die von dir verwendete Erinnerung an emalloc() während memory_get_usage(true) gibt Meilenstein zurück, der hier demonstriert werden kann Speicher Mile Store

Ich möchte wissen, wie nah das Skript war, um dieses Limit zu erreichen.

Das würde einiges an Mathematik erfordern und nur in Schleifen oder bestimmten Anwendungsfällen funktionieren. Warum habe ich das gesagt?

Vorstellen 

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.

Soweit ich weiß, kann ich nur den Speicher überprüfen, der für eine Variable oder einen bestimmten Abschnitt von PHP verwendet wird:

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

Siehe Erläuterung, aber wenn Sie sich in einer Schleife oder rekursiven Funktion befinden, können Sie die maximale Speichernutzung verwenden, um sicher abzuschätzen, wann der Speicher-Peek erreicht wird.

Beispiel 

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
}

Ausgabe 

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

Live-Demo 

Dies kann immer noch fehlschlagen

Es kann scheitern, weil nach if ($percentage > $peekPoint) {  Dies fügt noch hinzu, zusätzliche Aufgabe mit verbraucht auch Speicher

        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.

Fazit

Es ist keine perfekte Lösung, aber überprüfen Sie die Speicherkapazität im Intervall und ob der Wert größer ist (zB 90%) exit sofort und lass die schicken Sachen


29
2018-04-26 20:51



real_usage false meldet die Verwendung Ihres Skripts benutzt. Dies wird der genauere der beiden sein.

real_usage true meldet die Erinnerung zugeordnet zu deinem Skript. Dies wird der höhere der beiden sein.

Ich würde wahrscheinlich verwenden true Wenn ich versuchen würde zu vergleichen, da Ihr Skript nie mehr als Speicherlimit zugewiesen würde, würde es so lange laufen, wie es (plus alle anderen Skripte) diese Nutzung nicht überschritten hat.


7
2018-04-26 13:57



nach PHP memory_get_usage

real_usage

Setzen Sie dies auf TRUE, um den vom System zugewiesenen Gesamtspeicher einschließlich nicht verwendeter Seiten zu erhalten. Wenn nicht gesetzt oder FALSE, wird nur der belegte Speicher gemeldet.

Um den von Ihrem Skript verwendeten Speicher zu erhalten, sollten Sie memory_get_usage () verwenden, da der Standardwert real_usage false ist.

Wenn Sie den vom System zugewiesenen Speicher abrufen möchten, aber nicht wissen, wie viel tatsächlich verwendet wurde, verwenden Sie memory_get_usage (true);


1
2017-11-01 13:02