webman单进程内存爆掉不能仅靠memory_limit解决:因常驻运行,该配置只限单次脚本,需在start.php顶部用ini_set动态设置、配合monitor进程软重启(如max_memory=393216kb)及主动切断静态引用链。

Webman 单进程内存爆掉不是配置 memory_limit 就能解决的事——它常驻运行,memory_limit 只管单次脚本执行上限,而 Worker 进程会持续复用内存,不重启就不停涨。真要防止单个进程耗尽资源,得靠三件事:限制硬上限、主动归还、软重启兜底。
memory_limit 在 Webman 中到底生效在哪?
Webman 启动后走 CLI 模式(非 PHP-FPM),php.ini 里的 memory_limit 默认不生效;必须在进程启动早期动态设置,否则 worker 一跑起来就按默认值(通常 128M 或 -1)跑,极易触顶。
- 在
start.php最顶部(早于require自动加载和任何业务代码)加:ini_set('memory_limit', '384M'); - 别写
-1—— 这等于放弃防线,掩盖真实泄漏点 - CLI 启动时也可强制指定:
php -d memory_limit=512M start.php start -d,但该值会被start.php里后续ini_set覆盖 -
.htaccess和php_admin_value(FPM 配置)对 Webman 完全无效,别白改
为什么只设 memory_limit 不够?
因为 Webman 的 Worker 是长生命周期进程,memory_get_usage() 上涨后,PHP 不会自动把内存交还给操作系统;即使变量被 unset,底层内存块仍被进程持有,RSS(常驻集大小)持续攀升。你看到的“内存占用高”,往往不是 PHP 认为的“已用内存”,而是 OS 看到的“没还的物理内存”。
-
memory_get_usage(true)返回的是当前向 OS 申请的内存块总量,但它可能远低于ps aux看到的 RSS - GC(
gc_collect_cycles())能回收循环引用,但无法让 OS 回收空闲内存页 - 大数组、缓存、未关闭的连接句柄、静态类属性,都会让 RSS 持续累积,直到 OOM Killer 干掉进程
- 所以单靠
memory_limit只能防止“单次请求炸掉”,防不住“跑三天后内存涨到 2GB”
怎么让进程自己“知足常乐”并安全退出?
Webman 自带 monitor 进程,但它默认不启用;必须手动打开,并配阈值,才能实现“快撑爆时自动拉新进程、杀旧进程”的软重启策略。
- 在
config/app.php中开启监控:'monitor' => ['enable' => true] - 设置内存软上限(单位 KB):
'max_memory' => 393216(即 384MB),超过此值 monitor 会触发平滑重启对应 worker - 该机制不中断请求:新 worker 启动后,旧 worker 处理完当前请求再退出
- 注意:重启阈值必须低于系统
ulimit -v和memory_limit,否则还没触发 monitor 就先被 OS 杀了 - 配合日志观察效果:
tail -f storage/logs/monitor.log,能看到Worker #1 memory usage 395MB > 384MB, restart it类提示
真正难处理的不是“设多少 MB”,而是那些你以为清掉了、其实还被闭包或静态数组钉住的对象——它们会让 RSS 一路涨到阈值前都毫无征兆。监控 + 重启只是兜底,定位并切断隐式引用链,才是治本动作。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











