Вступ
Ви повинні використовувати memory_get_usage(false)
оскільки те, що ви хочете, це пам'ять, яка не виділена.
Яка різниця
Можливо, Google Mail
ви виділили 25MB
для вас місце для зберігання, але це не означає, що цим ви зараз користуєтесь.
Це саме те, що говорив документ PHP
Встановіть значення TRUE, щоб отримати реальний обсяг пам'яті, виділений із системи. Якщо не встановлено або FALSE, повідомляється лише про пам’ять, що використовується emalloc ().
Обидва аргументи повертають пам’ять, виділену щодо обмеження пам’яті, але головна різниця полягає в:
memory_get_usage(false)
надайте пам’ять, яку використовує emalloc()
while, memory_get_usage(true)
повертає віху, яку можна продемонструвати тут Memory Mile Store
Я хочу знати, наскільки близьким був сценарій, щоб досягти цієї межі.
Це зайняло б деяку математику і могло б працювати лише в циклах або конкретних випадках використання. Чому я сказав таке?
Уявіть
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
.
Наскільки я знаю, єдиним способом перевірити пам’ять, яка використовується для змінної чи конкретного розділу PHP, є:
$start_memory = memory_get_usage();
$foo = "Some variable";
echo memory_get_usage() - $start_memory;
Див. Пояснення , але якщо ви перебуваєте у циклі або рекурсивній функції, ви можете використовувати максимальне використання пам’яті, щоб безпечно оцінити, коли буде зафіксовано пам’ять.
Приклад
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
}
Демо в прямому ефірі
Це все одно може не вдатися
Можливо, це не вдасться, оскільки після 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;
If the memory to process this request is grater than the memory available the script would fail.
Висновок
Це не ідеальне рішення, але перевіряйте пам’ять з інтервалом, і якщо exit
миттєво перевищує (наприклад, 90%), залиште вишукані речі