Понимание memory_get_usage() и pmap

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

Более конкретно, звоня memory_get_peak_usage(true) каждая минута в моем PHP-скрипте возвращает значения в диапазоне от 1,75 до 3,5 МБ, тогда как типичный результат pmap -d PID дает что-то вроде:

...

b7839000       4 r---- 0000000000008000 0ca:00060 libcrypt-2.11.1.so
b783a000       4 rw--- 0000000000009000 0ca:00060 libcrypt-2.11.1.so
b783b000     156 rw--- 0000000000000000 000:00000   [ anon ]
b7864000       8 rw--- 0000000000000000 000:00000   [ anon ]
b7867000      12 r-x-- 0000000000000000 0ca:00060 libgpg-error.so.0.4.0
b786a000       4 r---- 0000000000002000 0ca:00060 libgpg-error.so.0.4.0
b786b000       4 rw--- 0000000000003000 0ca:00060 libgpg-error.so.0.4.0
b786c000       4 r---- 0000000000000000 000:00000   [ anon ]
b786d000      16 rw--- 0000000000000000 000:00000   [ anon ]
b7871000     108 r-x-- 0000000000000000 0ca:00060 ld-2.11.1.so
b788c000       4 r---- 000000000001a000 0ca:00060 ld-2.11.1.so
b788d000       4 rw--- 000000000001b000 0ca:00060 ld-2.11.1.so
bffc7000     136 rw--- 0000000000000000 000:00000   [ stack ]
f57fe000       4 r-x-- 0000000000000000 000:00000   [ anon ]
mapped: 32740K    writeable/private: 13116K    shared: 28K

Если я правильно понимаю, показатель записи / приватности является наиболее релевантным, поскольку это память, используемая исключительно процессом. Почти 13 МБ - это очень далеко от суммы, сообщенной memory_get_peak_usage(true), Может кто-нибудь объяснить, пожалуйста, несоответствие?

2 ответа

Я понимаю, что memory_get_peak_usage() вернет количество памяти, используемой вашим скриптом. Так что это не включая накладные расходы PHP.

Возвращает пик памяти, в байтах, который был выделен вашему скрипту PHP.

Вы можете уменьшить объем памяти, которую использует PHP, компилируя меньшее количество расширений.

PHP сам по себе является крупным приложением, особенно с расширениями по умолчанию. Мы (как разработчики PHP) можем написать простой код вроде simplexml_load_string() и наблюдайте, как происходит волшебство, но код, приводящий эту магию в действие, где-то в памяти. Глядя на вывод phpinfo() покажет, сколько расширений установлено. Внутри PHP находится код, который возьмет ваш PHP и преобразует его в OPCODE, а затем код, который выполняет эти коды операций. Каждый экземпляр PHP при его выполнении будет нести эти накладные расходы.

Такое использование памяти явно нетривиально, но следовало ожидать. Если бы вам пришлось писать весь код для обработки входящих GET/POST/FILES, управляйте XML, файлами, потоковой магией и т. Д. Использование памяти быстро увеличилось бы.

В результате обычная техника производительности - удалить все ненужные расширения, чтобы уменьшить размер исполняемого файла. Для серверов с ограниченным объемом памяти (которые являются наиболее загруженными) удаление нескольких расширений и снижение использования памяти с 9 до 7 мегабайт приводит к увеличению числа работающих Apache.

Эти накладные расходы не разделяются, потому что каждое выполнение действительно является отдельной копией выполняемого PHP. Доступны альтернативы с использованием потоковобезопасных сборок, но не все расширения PHP являются поточно-ориентированными.

Удаление расширений Посмотрите на функции, которые вы используете. mysqli_*? xml_*? и т.д. Также взгляните на то, как строится PHP, вот моя строка конфигурации:

Configure Command => './configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-mysql=mysqlnd' '--with-gd' '--enable-soap' '--with-libxml-dir=/usr/lib/' '--with-mysql-sock=/tmp' '--with-tidy' '--with-jpeg-dir=/usr/lib/' '--with-xsl' '--with-curl' '--with-zlib' '--enable-gd-native-ttf' '--with-openssl' '--with-mcrypt' '--with-pdo-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-bz2' '--enable-bcmath'

Если бы я экономил память, я бы начал с построения PHP с ./configure --disable-all (для удаления расширений по умолчанию), затем добавление только тех расширений, которые я недавно использовал. Я не пользуюсь libxml для моего кода больше, ни soap так что я могу отбросить эти биты. Я могу отдать на аутсорсинг tidy работать на шестерёнку и командную строку, так что я это тоже потяну. Затем запустить мой код (здесь было бы неплохо провести модульное тестирование) и посмотреть, что сломалось. Перестройте PHP с необходимым расширением, промойте и повторите. Очевидно, не делайте этого в производстве, или у вас будет плохое время.

Байты против битов имеют коэффициент 10 из. Следовательно, 1,3 МБ = 13 Мбит

Другие вопросы по тегам