PHP-FPM内存控制核心是调低pm.max_children等动态进程参数,而非单进程内存限制;512MB机器建议设为pm.max_children=2、start/min/max_spare_servers=1,并重载服务验证生效。

怎么用 pm 配置控制 PHP-FPM 实际内存开销
PHP-FPM 内存占用不是靠“限制单个进程”来管的,而是靠控制它最多能 fork 出多少个子进程——每个 php-fpm 子进程常驻内存约 25–40MB(取决于扩展和代码),50 个就轻松吃掉 1.5GB。所以核心是把 pm.max_children 打下来,而不是幻想给每个进程硬设 RSS 上限。
-
pm = dynamic是默认也最常用的方式,但必须同步调低pm.start_servers、pm.min_spare_servers和pm.max_spare_servers,否则空闲时也会维持大量进程 - 512MB 内存机器建议设为:
pm.max_children = 2、pm.start_servers = 1、pm.min_spare_servers = 1、pm.max_spare_servers = 1 - 1GB 内存可放宽到
pm.max_children = 3,再往上每加 1 个子进程,就要多留出至少 30MB 可用内存余量 - 别乱切到
pm = static——它会让进程数永远卡死在pm.max_children,哪怕没请求也占着内存,对低配机反而更不友好
为什么改了 www.conf 还不生效?常见配置失效原因
宝塔里改完 /www/server/php/{版本号}/etc/php-fpm.d/www.conf 文件,却看到 ps aux | grep php-fpm 进程数没变,大概率是没重载服务,或配置写错位置。
- 必须执行
sudo service php-fpm-{版本号} reload(如php-fpm-74),重启会中断请求,重载才是平滑生效的正确操作 - 检查是否误改了全局
/www/server/php/{版本号}/etc/php-fpm.conf——那里只有[global]段,pm.*参数只在[www]段下才有效 - 确认没被
.user.ini或php_admin_value[memory_limit]干扰:前者不影响进程数,后者只管单脚本内存上限,和 FPM 进程管理无关 - 改完务必运行
/www/server/php/{版本号}/sbin/php-fpm -t,输出test is successful才算语法过关
memory_limit 和 pm.max_children 到底谁先咬住内存?
这是最容易混淆的一对参数:memory_limit 是 PHP 脚本自己能 malloc 的上限,而 pm.max_children 是 FPM 能同时跑几个这样的脚本。它们不是叠加关系,而是先后触发。
- 一个请求进来,FPM 先找空闲子进程;如果全忙且已达
pm.max_children,新请求就排队或直接 502 - 一旦分配到子进程,该进程内脚本若超
memory_limit(比如读大文件没分块),就会报Fatal error: Allowed memory size of XXX bytes exhausted,但这个进程还活着,继续等下一个请求 - 所以:
pm.max_children防的是“并发压垮服务器”,memory_limit防的是“单请求拖垮进程”——两者得一起调,不能只盯一个 - 例如 512MB 机器上,
pm.max_children = 2+memory_limit = 128M是合理组合;若把memory_limit拉到 512M,两个进程就可能瞬间吃光所有内存
如何验证当前配置真正在跑?别信面板显示
宝塔面板里点“重载配置”后,界面上的数字只是你填进去的值,不代表 PHP-FPM 进程实际加载了它。真实情况得看运行时状态。
立即学习“PHP免费学习笔记(深入)”;
- 查当前生效的子进程数:
ps aux | grep 'php-fpm:.+pool.www' | grep -v grep | wc -l - 看 FPM 自己的统计页(需开启
pm.status_path = /status):curl http://127.0.0.1/status?full,重点关注active processes和max active processes - 检查实际加载的配置路径:
/www/server/php/{版本号}/sbin/php-fpm -i | grep "Configuration File",确认你编辑的确实是那个www.conf - 最狠一招:临时把
pm.max_children改成 1,保存重载,然后开两个浏览器标签同时刷新同一个 PHP 页面——第二个必然卡住或 502,这就说明限制已起效
复杂点在于:FPM 的动态伸缩有延迟,空闲进程不会秒退,要等 pm.process_idle_timeout(默认 10s)之后才回收。所以刚改完别急着看 ps,等十几秒再观察。



















