Если real_usage
аргумент установлен true
в PHP DOCS, говорят, что он получит реальный размер памяти, выделенной из системы. Если это false
будет информация о памятиemalloc()
Какой из этих двух вариантов возвращает макс. память, выделенная относительно значения ограничения памяти в php.ini?
Я хочу знать, насколько близко был сценарий к достижению этого предела.
php
memory
memory-management
thelolcat
источник
источник
Ответы:
Хорошо, давайте проверим это с помощью простого скрипта:
ini_set('memory_limit', '1M'); $x = ''; while(true) { echo "not real: ".(memory_get_peak_usage(false)/1024/1024)." MiB\n"; echo "real: ".(memory_get_peak_usage(true)/1024/1024)." MiB\n\n"; $x .= str_repeat(' ', 1024*25); //store 25kb more to string }
Выход:
not real: 0.73469543457031 MiB real: 0.75 MiB not real: 0.75910949707031 MiB real: 1 MiB ... not real: 0.95442199707031 MiB real: 1 MiB not real: 0.97883605957031 MiB real: 1 MiB PHP Fatal error: Allowed memory size of 1048576 bytes exhausted (tried to allocate 793601 bytes) in /home/niko/test.php on line 7
Похоже, что реальное использование - это память, выделенная из системы, которая, кажется, распределяется в более крупных сегментах, чем в настоящее время требуется скрипту. (Я думаю, из соображений производительности). Это также память, которую использует процесс php.
$real_usage = false
Использование является использование памяти вы на самом деле используется в сценарии, а не фактический объем памяти , выделенный менеджером памяти Zend.Прочтите этот вопрос для получения дополнительной информации.
Вкратце: чтобы узнать, насколько вы приблизились к пределу памяти, используйте
$real_usage = true
источник
if (segment_size < true_size || heap->real_size + segment_size > heap->limit) { /* Memory limit overflow */
.emalloc
(плюс байты для заголовков и выравнивания памяти). Он не отражает потери памяти из-за того, что блоки не помещаются в пространство, оставшееся в уже выделенных сегментах. Если вы измените свой пример на выделение (1024 * 256) байтов и ограничение 2M, разница в два станет более очевидной.memory_get_usage(true)
Значение возвращается , которые должны быть сопоставлены сmemory_limit
. Пример, приведенный в ответе, слишком прост, поскольку нет «потраченной впустую» памяти. Происходит то, что «реальную» выделенную память необходимо увеличить с «1 МБ» до «1,25 МБ», и это вызывает фатальную ошибку. . у меня есть сложный пакетный скрипт с лимитом памяти 120 Мбайт , которые имеют «не реально» выделенную память только «80 МиБа» , когда она будет прервана , так как «реальная» выделенная память достигает предел.Введение
Вы должны использовать,
memory_get_usage(false)
потому что вы хотите использовать память, а не выделенную память.Какая разница
Ваша
Google Mail
мощь распределили25MB
хранения для вас , но это не значит , что это то , что вы использовали в данный момент.Это именно то, что говорилось в документе PHP
Оба аргумента будут возвращать память, выделенную относительно лимита памяти, но главное отличие:
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; // 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%) и оставляйте причудливые вещиисточник
memory_limit
вариант насчет кучи? или стек?real_usage
ложные сообщения об использовании сценария используется . Это будет более точным из двух.real_usage
true сообщает об объеме памяти, выделенной вашему скрипту. Это будет более высокий из двух.Я бы, вероятно, использовал,
true
если бы пытался сравнить, так как ваш сценарий никогда не будет выделяться больше, чем предел памяти, и будет продолжать работать до тех пор, пока он (плюс все другие сценарии) не превысит это использование.источник
false
это память сценарий используется ,true
это память выделяется .согласно PHP memory_get_usage
поэтому, чтобы получить память, используемую вашим скриптом, вы должны использовать memory_get_usage (), поскольку по умолчанию real_usage имеет значение false.
если вы хотите получить память, выделенную системой, но не заботитесь о том, сколько фактически было использовано, используйте memory_get_usage (true);
источник
<!-- Print CPU memory and load --> <?php $output = shell_exec('free'); $data = substr($output,111,19); echo $data; echo file_get_contents('/proc/loadavg'); $load = sys_getloadavg(); $res = implode("",$load); echo $res; ?>
источник