Intereting Posts

memory_get_peak_usage () с "реальным использованием"

Если аргумент real_usage установлен в true PHP DOCS скажет, что он получит реальный размер памяти, выделенной из системы. Если он false он получит память, сообщенную emalloc()

Какой из этих двух вариантов возвращает max. память распределена относительно предельного значения памяти в php.ini?

Я хочу знать, насколько близок сценарий для достижения этого предела.

Хорошо, давайте протестируем это, используя простой скрипт:

 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

Введение

Вы должны использовать memory_get_usage(false) потому что вы хотите использовать память, а не выделенную память.

Какая разница

Возможно, ваша Google Mail выделила вам 25MB памяти, но это не значит, что это то, что вы использовали на данный момент.

Это именно то, что говорил PHP-документ.

Установите для этого значение ИСТИНА, чтобы получить реальный размер памяти, выделенной из системы. Если не задано или 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; // 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.

Вывод

Это не идеальное решение, но проверяйте память в промежутке и, если ее превышение заглядывает (например, 90%), exit мгновенно и оставляем причудливые вещи

real_usage false сообщает об использовании вашего скрипта. Это будет более точное из двух.

real_usage true сообщает память, выделенную для вашего скрипта. Это будет больше из двух.

Я бы, вероятно, использовал true если бы пытался сравнить, так как ваш сценарий никогда не будет выделяться больше, чем ограничение памяти, и будет продолжать работать до тех пор, пока он (плюс все остальные скрипты) не будет превышать это использование.

в соответствии с PHP memory_get_usage

real_usage

Установите для этого значение ИСТИНА, чтобы получить общую память, выделенную из системы, включая неиспользуемые страницы. Если не установлено или FALSE, сообщается только используемая память.

поэтому для получения памяти, используемой вашим скриптом, вы должны использовать memory_get_usage (), поскольку по умолчанию real_usage является ложным.

если вы хотите получить память, выделенную системой, но все равно, сколько было использовано, используйте memory_get_usage (true);