У меня проблема с Apache и PHP7 на Debian ... Он автоматически настраивается apt ... мои скрипты выполняют много вычислений с большим объемом используемой памяти (ограничение - 512 МБ). Но я заметил, что каждый раз, когда я запускаю скрипт с разными параметрами, /usr/sbin/apache2 -k start
использует все больше и больше памяти ... кажется, что она не освобождается должным образом. Есть идеи, как это исправить? Или как узнать, что именно вызывает это?
Проблема серьезная и заканчивается mmap() failed: [12] Cannot allocate memory
в Apache и PHP Fatal error: Out of memory
в PHP. При использовании 100% общей памяти (которая никогда не освобождается) и невозможности сделать что-либо еще.
Кажется, он не убивает новые порожденные процессы после подключения ...
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
12123 www-data 20 0 369M 117M 7272 S 0.0 *6.0* 0:18.40 /usr/sbin/apache2 -k start
12132 www-data 20 0 357M 105M 7272 S 0.0 *5.4* 0:17.96 /usr/sbin/apache2 -k start
12122 www-data 20 0 333M 84296 7860 S 0.0 *4.2* 0:18.35 /usr/sbin/apache2 -k start
12133 www-data 20 0 311M 61160 7272 S 0.0 *3.1* 0:08.00 /usr/sbin/apache2 -k start
12131 www-data 20 0 293M 42732 7272 S 0.0 *2.1* 0:17.70 /usr/sbin/apache2 -k start
12134 www-data 20 0 291M 40676 7272 S 0.0 *2.0* 0:08.32 /usr/sbin/apache2 -k start
12124 www-data 20 0 275M 25040 7900 S 0.0 *1.2* 0:16.19 /usr/sbin/apache2 -k start
12125 www-data 20 0 265M 13084 6768 S 0.0 *0.7* 0:00.01 /usr/sbin/apache2 -k start
12128 www-data 20 0 265M 13060 6708 S 0.0 *0.7* 0:00.01 /usr/sbin/apache2 -k start
12126 www-data 20 0 265M 9468 3332 S 0.0 *0.5* 0:00.00 /usr/sbin/apache2 -k start
Значение между *
является MEM%
из htop
. Каждый новый расчет порождает новый процесс. А другие используют все больше и больше памяти ...
apache2 -l
Compiled in modules:
core.c
mod_so.c
mod_watchdog.c
http_core.c
mod_log_config.c
mod_logio.c
mod_version.c
mod_unixd.c
a2query -M
prefork
Вы видите нормальное поведение при использовании mod_php с prefork apache2.
Когда скрипт php запускается в предварительно созданном процессе, в этом предварительно созданном процессе apache есть что-то вроде «буфера памяти PHP». Он увеличивается всякий раз, когда выполняющийся скрипт требует больше памяти, чем уже выделено, но сжимается только при повторном использовании предварительно созданного процесса (т.е. перезапуске).
Вы можете решить эту проблему, установив ServerLimit
и MaxClients
to (системная память / php memory_limit), что приведет к не более чем этому количеству предварительно загруженных процессов. Это число, умноженное на ваш php memory_limit, поместится в памяти.
Вы также можете установить MaxRequestsPerChild 1
, но это очень плохо скажется на производительности.
В долгосрочной перспективе вам, вероятно, следует перейти на php-fpm и тщательно спланировать максимальное количество процессов php с учетом их потребления памяти.