我在 Debian 上使用 Apache 和 PHP7 时遇到了问题...它由 apt 自动配置...我的脚本进行大量计算,占用大量内存(限制 - 512MB)。但我注意到,每次我使用不同的参数运行脚本时,/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
答案1
您所看到的是使用 mod_php 与 apache2 prefork 时的正常行为。
当 php 脚本在预分叉进程中运行时,该预分叉 apache 进程中会存在类似“PHP 内存缓冲区”的东西。每当运行脚本需要的内存超过已分配的内存时,该缓冲区就会增大,但只有在回收(即重新启动)预分叉进程时才会缩小。
您可以通过将ServerLimit
和设置MaxClients
为(系统内存 / php memory_limit)来缓解该问题,这将导致预分叉进程的数量不超过该数量。该数字乘以 php memory_limit 将适合内存。
您也可以设置MaxRequestsPerChild 1
,但这会对性能产生非常糟糕的影响。
从长远来看,您可能应该迁移到 php-fpm,并仔细规划 php 进程的最大数量及其内存消耗。