为什么 PHP-FPM 子进程退出码 137 表示内存不足如何调整?

文章导读
PHP-FPM 子进程退出码 137 表示进程被 SIGKILL 信号终止(128+9=137),通常由 Linux OOM Killer 触发,在 2GB 内存服务器上若 php-fpm 进程数设置为 50 个,每个进程占用 1%-2.5% 内存,极易触发内存耗尽。
📋 目录
  1. 原因分析
  2. 解决方案一:调整 PHP-FPM 进程池配置
  3. 解决方案二:设置单进程内存限制
  4. 解决方案三:代码层内存优化
  5. 注意事项
  6. 参考来源
A A

PHP-FPM 子进程退出码 137 表示进程被 SIGKILL 信号终止(128+9=137),通常由 Linux OOM Killer 触发,在 2GB 内存服务器上若 php-fpm 进程数设置为 50 个,每个进程占用 1%-2.5% 内存,极易触发内存耗尽。

原因分析

退出码 137 的本质是进程收到 SIGKILL 信号(信号编号 9),根据 Unix/Linux 退出码规则,128 系列退出码表示 128+n(n 为信号编号),因此 128+9=137。当系统物理内存不足时,Linux 内核的 OOM Killer 会强制终止占用内存最高的进程,php-fpm 子进程因数量过多或单个进程内存泄漏常成为目标。在 2GB 内存服务器实测案例中,可用内存仅剩 70M 时内存使用率高达 92%,此时数据库服务会被挤掉导致服务挂断。

解决方案一:调整 PHP-FPM 进程池配置

编辑 php-fpm 池配置文件,路径通常为/etc/php/8.1/fpm/pool.d/www.conf 或/etc/php-fpm.d/www.conf。找到 pm.max_children 字段,若其值过大(如 50),需调小至合理范围。对于 1GB 内存 VPS,php-fpm 进程数建议设置为 10-20 之间,计算公式为:进程数=内存/2/30。同时检查 pm.max_spare_servers 和 pm.min_spare_servers,这两个值均不能大于 pm.max_children,通常 pm.max_spare_servers 设置为 pm.max_children 值的 60%-80%。配置示例:pm = dynamic、pm.max_children = 15、pm.start_servers = 8、pm.min_spare_servers = 6、pm.max_spare_servers = 15。修改后执行 systemctl restart php-fpm 重启服务。

解决方案二:设置单进程内存限制

在 php-fpm.conf 或池配置文件中添加 php_admin_value[memory_limit] = 256M 指令。php_admin_value 具有更高优先级,不能被.htaccess 文件或 ini_set() 函数覆盖,而 php_value 则可被覆盖。对于 1GB 物理内存 VPS,推荐 memory_limit = 64M,够用且留余量,超了说明代码有问题。同时配置 opcache.memory_consumption = 64,开启 OPcache 后字节码缓存能省掉每次 include/require 的解析开销,比调 memory_limit 更有效。注意 opcache.memory_consumption 盲目调到 256 或 512 会导致每个 php-fpm 进程 RSS 增加 10-20MB。

为什么 PHP-FPM 子进程退出码 137 表示内存不足如何调整?

解决方案三:代码层内存优化

禁用 xdebug 扩展,它会让内存占用翻倍甚至更多,生产环境必须关闭。数据库大批量查询时禁用 PDO::FETCH_ASSOC 全缓存,改用游标分页:SELECT * FROM table WHERE id > ? ORDER BY id LIMIT 1000。处理超大文本文件时避免 file_get_contents(),改用 fopen()+fgets() 逐行读取。图像处理时 imagecreatefromjpeg() 加载 5MB JPG 可能瞬占 200MB 内存,务必用 imagedestroy() 及时释放。在脚本开头调用 ini_set('memory_limit', '384M') 可临时调整,但该调用不能高于 php.ini 中设定的硬上限。

注意事项

第一,memory_limit 不是越大越好,盲目调到 512M 可能让一次泄漏拖垮整个 FPM 进程池。第二,opcache.save_comments=0 在 Laravel/Symfony 项目中必须添加,注释不参与执行却占 opcache 空间。第三,若 interned_strings_usage 接近上限,需调高 opcache.interned_strings_buffer(如设为 16 或 32),默认仅 8。第四,Composer 应执行 composer dump-autoload --optimize --classmap-authoritative 生成完整 classmap,避免 ClassLoader::findFile() 反复扫描 vendor 目录累积数 MB 临时字符串。第五,对象间存在双向引用时,PHP 7.4+ 虽有 GC 改进,但小内存下仍建议显式断引用:unset($obj->parent)。

参考来源

来源:Linux 系统文档 - 进程退出码 128 系列规则(128+n,n 为信号编号)

为什么 PHP-FPM 子进程退出码 137 表示内存不足如何调整?

来源:宝塔面板官方文档 - PHP-FPM 进程内存限制调整(2026 年 3 月 17 日)

来源:PHP 内存优化实践 - 1GB 内存 VPS 配置案例(2025 年 9 月 11 日)

来源:PHP-FPM 配置指南 - php_admin_value 与 php_value 优先级说明(2025 年 8 月 11 日)