Введение
Вы должны использовать, memory_get_usage(false)
потому что вы хотите использовать память, а не выделенную память.
Какая разница
Ваша Google Mail
мощь распределили 25MB
хранения для вас , но это не значит , что это то , что вы использовали в данный момент.
Это именно то, что говорилось в документе PHP
Установите значение TRUE, чтобы получить реальный размер памяти, выделенной системой. Если не установлено или FALSE, сообщается только память, используемая emalloc ().
Оба аргумента будут возвращать память, выделенную относительно лимита памяти, но главное отличие:
memory_get_usage(false)
указать объем памяти, используемый в emalloc()
то время как 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;
$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);
}
Выход
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%) и оставляйте причудливые вещи