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.
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
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
}
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
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
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.
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).
<!-- 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;
?>