web-dev-qa-db-de.com

memory_get_peak_usage () mit "real usage"

Wenn das Argument real_usage Auf true gesetzt ist, erhalten die PHP= DOCS die tatsächliche Größe des vom System zugewiesenen Speichers. Wenn es sich um false Es wird der von emalloc() gemeldete Speicher abgerufen.

Welche dieser beiden Optionen gibt die max. Speicherbelegung relativ zum Speichergrenzwert in der php.ini?

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

83
thelolcat

Ok, testen wir dies mit einem einfachen Skript:

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

Scheint, als wäre die tatsächliche Nutzung der vom System zugewiesene Speicher, der offenbar in größeren Eimern zugewiesen wird, als das Skript derzeit benötigt. (Ich denke aus Performancegründen). Dies ist auch der Speicher, den der PHP-Prozess verwendet.

Das $real_usage = false usage ist die Speicherauslastung, die Sie tatsächlich in Ihrem Skript verwendet haben, nicht die tatsächliche Speichermenge, die vom Zend-Speichermanager zugewiesen wurde.

Lesen Sie diese Frage für weitere Informationen.

Kurz gesagt: Um zu erfahren, wie nahe Sie an der Speichergrenze sind, verwenden Sie $real_usage = true

121
Niko Sams

Einführung

Sie sollten memory_get_usage(false) verwenden, da der verwendete Speicher nicht zugeordnet ist.

Was ist der Unterschied

Ihr Google Mail Hat möglicherweise 25MB Speicherplatz für Sie reserviert, dies bedeutet jedoch nicht, dass Sie diesen momentan verwendet haben.

Genau das hat das PHP doc gesagt

Setzen Sie dies auf TRUE, um die tatsächliche Größe des vom System zugewiesenen Speichers abzurufen. Wenn nicht gesetzt oder FALSE, wird nur der von emalloc () verwendete Speicher gemeldet.

Beide Argumente würden den relativ zum Speicherlimit zugewiesenen Speicher zurückgeben, der Hauptunterschied ist jedoch:

memory_get_usage(false) gibt den von emalloc() verwendeten Speicher an, während memory_get_usage(true) einen Meilenstein zurückgibt, der hier demonstriert werden kann Memory Mile Store

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

Das würde ein wenig Mathe kosten und könnte nur in Schleifen oder bestimmten Anwendungsfällen funktionieren. Warum habe ich das gesagt?

Stell dir vor

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 in einer rekursiven Funktion befinden, können Sie die maximale Speichernutzung verwenden, um sicher abzuschätzen, wann ein Speicher-Peek erreicht werden würde.

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

Dies kann fehlschlagen, da nach if ($percentage > $peekPoint) { immer noch zusätzliche Aufgaben hinzugefügt werden, die ebenfalls Speicher belegen

        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 prüfen Sie in regelmäßigen Abständen, ob Speicherplatz verfügbar ist, und wenn der Wert für peek (z. B. 90%) überschritten wird, exit sofort und verlassen Sie das ausgefallene Zeug

33
Baba

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

real_usage true meldet den Speicher zugewiesen an Ihr Skript. Dies wird der höhere der beiden sein.

Ich würde wahrscheinlich true verwenden, wenn ich versuchen würde zu vergleichen, da Ihrem Skript niemals mehr als ein Speicherlimit zugewiesen würde und es weiterhin ausgeführt werden würde, solange es (plus alle anderen Skripte) das nicht überschreitet Verwendung.

7
Glitch Desire

wie pro PHP memory_get_usage

real_usage

Setzen Sie diesen Wert auf TRUE, um den gesamten vom System zugewiesenen Speicher abzurufen, einschließlich nicht verwendeter Seiten. 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 für real_usage false ist.

wenn Sie den vom System zugewiesenen Speicher abrufen möchten, sich aber nicht darum kümmern möchten, wie viel tatsächlich verwendet wurde, verwenden Sie 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