introduzione
Dovresti usare memory_get_usage(false)perché quello che vuoi è la memoria usata non la memoria allocata.
Qual è la differenza
Il vostro Google Mailpotrebbe avere assegnato 25MBdi 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%) exitimmediatamente e lascia le cose fantasiose