Wprowadzenie
Powinieneś użyć, memory_get_usage(false)
ponieważ to, czego chcesz, to pamięć używana, a nie przydzielona.
Co za różnica
Być Google Mail
może przeznaczyłeś 25MB
dla Ciebie miejsce na dane, ale nie oznacza to, że właśnie tego używałeś.
Dokładnie to mówi dokument PHP
Ustaw to na TRUE, aby uzyskać rzeczywisty rozmiar pamięci przydzielonej z systemu. Jeśli nie jest ustawione lub FALSE, raportowana jest tylko pamięć używana przez emalloc ().
Oba argumenty zwróciłyby pamięć przydzieloną względem limitu pamięci, ale główna różnica jest taka:
memory_get_usage(false)
Podaj pamięć używaną przez emalloc()
while memory_get_usage(true)
zwraca kamień milowy, który można zademonstrować tutaj Memory Mile Store
Chcę wiedzieć, jak blisko było osiągnięcie tego limitu przez skrypt.
Wymagałoby to trochę matematyki i może działać tylko w pętlach lub w określonych przypadkach użycia. Dlaczego tak powiedziałem?
Wyobrażać sobie
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
.
O ile wiem, jedynym sposobem na sprawdzenie pamięci używanej dla zmiennej lub określonej sekcji PHP jest:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
Zobacz Wyjaśnienie , ale jeśli jesteś w pętli lub funkcji rekurencyjnej, możesz użyć maksymalnego użycia pamięci, aby bezpiecznie oszacować, kiedy zostanie osiągnięty wgląd w pamięć.
Przykład
ini_set('memory_limit', '1M');
$memoryAvailable = filter_var(ini_get("memory_limit"), FILTER_SANITIZE_NUMBER_INT);
$memoryAvailable = $memoryAvailable * 1024 * 1024;
$peekPoint = 90;
$memoryStart = memory_get_peak_usage(false);
$memoryDiff = 0;
$stat = array(
"HIGHEST_MEMORY" => 0,
"HIGHEST_DIFF" => 0,
"PERCENTAGE_BREAK" => 0,
"AVERAGE" => array(),
"LOOPS" => 0
);
$data = "";
$i = 0;
while ( true ) {
$i ++;
$memoryUsed = memory_get_peak_usage(false);
$memoryDiff = $memoryUsed - $memoryStart;
$memoryStart = memory_get_peak_usage(false);
$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;
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);
}
Wynik
Stoped at: 95.86%
{
"HIGHEST_MEMORY": "0.71",
"HIGHEST_DIFF": "0.24",
"PERCENTAGE_BREAK": "95.86%",
"AVERAGE": "0.04",
"LOOPS": 11
}
Live Demo
To wciąż może się nie powieść
Może się nie powieść, ponieważ po if ($percentage > $peekPoint) {
tym nadal dodaj, aby wykonać dodatkowe zadanie, a także zużywa pamięć
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.
Wniosek
Nie jest to idealne rozwiązanie, ale sprawdzaj pamięć co jakiś czas i jeśli przekracza ona peek (np. 90%) exit
natychmiast i zostaw wymyślne rzeczy