introduzione
Dovresti usare memory_get_usage(false)
perché quello che vuoi è la memoria usata non la memoria allocata.
Qual è la differenza
Il vostro Google Mail
potrebbe avere assegnato 25MB
di archiviazione per voi, ma ciò non significa che sia quello che avete utilizzato al momento.
Questo è esattamente ciò che diceva il documento PHP
Impostalo su TRUE per ottenere la dimensione reale della memoria allocata dal sistema. Se non impostato o FALSE viene riportata solo la memoria utilizzata da emalloc ().
Entrambi gli argomenti restituiscono la memoria allocata rispetto al limite di memoria, ma la differenza principale è:
memory_get_usage(false)
dare la memoria utilizzata da emalloc()
while memory_get_usage(true)
restituisce milestone che può essere dimostrata qui Memory Mile Store
Voglio sapere quanto è stato vicino lo script a raggiungere quel limite.
Ciò richiederebbe un po 'di matematica e potrebbe funzionare solo in loop o casi d'uso specifici. Perché l'ho detto?
Immaginare
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
.
Per quanto ne so, l'unico modo in cui posso controllare la memoria utilizzata per una variabile o una sezione specifica di PHP è:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
Vedere la spiegazione , ma se ci si trova in un ciclo o in una funzione ricorsiva è possibile utilizzare il massimo utilizzo della memoria per stimare in modo sicuro quando verrà raggiunto il peek di memoria.
Esempio
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
}
Produzione
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
Dimostrazione dal vivo
Questo potrebbe ancora fallire
Potrebbe non riuscire perché dopo if ($percentage > $peekPoint) {
questo ancora aggiungere per fare attività aggiuntive consuma anche memoria
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.
Conclusione
Non è una soluzione perfetta, ma controlla la memoria a intervalli e se supera la sbirciatina (ad esempio il 90%) exit
immediatamente e lascia le cose fantasiose