Я наткнулся на memory_get_usage()
и memory_get_peak_usage()
.
Проблема в том, что я обнаружил, что эти две функции не обеспечивают реальную память, используемую текущим скриптом. Мой тестовый скрипт:
<?php echo memory_get_usage(); echo '<br />'; $a = str_repeat('hello', 100000); echo '<br />'; echo memory_get_usage(); echo '<br />'; echo memory_get_peak_usage(); ?>
Что возвращает:
355120
5355216
5356008
Что вы понимаете из этого?
Первое значение перед выполнением str_repeat()
поэтому оно должно быть значением 0
.
Второй – после процесса, и это нормально, чтобы иметь значение больше 0
но не такое большое значение.
Третий – это «пиковое» значение, и он немного больше второго, поскольку я думаю, что это должно быть самое большое значение в обработке микросекунды.
Итак, как вы думаете, реальная ценность потребления памяти текущего сценария должна быть такой:
memory_usage = the second memory usage - the first memory usage peak_memory_usage = the third (peak_usage) - the first memory usage
который дает:
1) 5355216 – 355120 = 5000096 байт
2) 5356008 – 355120 = 5000888 байт
Если это так, я полагаю, что первые 355120
байтов – это вся выделенная системой память, используемая apache и другими модулями, поскольку первое значение никогда не изменяется при увеличении или уменьшении количества повторений в str_repeat()
, только два значения после процесса увеличиваются или уменьшаются, но никогда не становятся меньше первого значения.
Согласно руководству php, memory_get_usage возвращает объем памяти, выделенный для php, не обязательно используемую сумму.
Хорошо, ваше первое утверждение о том, что первый memory_get_usage () должен быть 0, неверен. Согласно документации PHP:
Возвращает объем памяти в байтах, который в настоящее время выделяется для вашего PHP-скрипта.
Ваш скрипт запущен, поэтому он должен иметь выделенную память. Первый звонок информирует вас о том, что это такое.
Второе утверждение, что str_repeat () не должно использовать столько памяти, не смотрит на всю картину.
У вас есть строка «hello» (которая использует 5 байт), повторенную 100 000 раз, в общей сложности 500 000 байт … минимум. Вопрос в том, как PHP выполнял это действие? Используют ли они такой код? (Псевдокод):
s = "" for(i=0; i<100000; i++) s += "hello"
Этот код потребует перераспределения новой строки для каждой итерации цикла for. Теперь я не могу притворяться, что знаю, что PHP реализует str_repeat (), но вы должны быть предельно осторожны с тем, как вы используете память для уменьшения использования памяти. С появлением вещей они не управляли памятью в этой функции, как могли бы.
В-третьих, разница между использованием пиковой памяти и текущим использованием памяти зависит от стека, который необходим для вызова функции str_repeat (), а также любых локальных переменных, необходимых в этой функции. Возможно, память вернулась, когда функция вернулась.
Наконец, Apache работает в другом процессе, и мы имеем дело с виртуальной памятью. Ничто из того, что делает Apache, не повлияет на результат memory_get_usage (), поскольку процессы не разделяют виртуальную память.
В моем случае (PHP 5.3.3 в Mac OS X 10.5) ваш сценарий печатает:
323964
824176
824980
Теперь разница между вторым измерением и первым дает 500212, что очень близко к длине «привет» (5) раз 100 000. Поэтому я бы не сказал сюрпризов. Пик немного больше из-за некоторых временных распределений при оценке этих утверждений.
(На ваши другие вопросы уже ответили)