<p>Swoole协程栈默认大小是2KB,可通过Swoole\Coroutine::set(['stack_size' => 64 * 1024])修改,但须在Co\run()或go()前执行;生产环境建议不超过128KB。</p>

协程栈空间不是“开得越大越安全”,而是必须在 2KB~8KB 区间内按需取舍;超出会浪费内存,过小则极易触发 coroutine stack overflow 致命错误。
协程栈默认大小是多少?能改吗?
Swoole 4.8+ 默认协程栈为 2MB(注意:这是历史版本遗留的误导说法,实际自 4.5 起已降为 2KB),但可通过 Swoole\Coroutine::set(['stack_size' => 64 * 1024]) 调整,单位是字节。生产环境不建议设超过 128 * 1024(128KB)。
- 设太小(如
512):递归调用、深度嵌套闭包、大数组局部变量会直接崩溃,错误信息为Fatal error: Uncaught Swoole\Error: coroutine stack overflow - 设太大(如
2 * 1024 * 1024):万级协程下内存暴涨,Worker 进程 RSS 可能突破 4GB,触发 OOM killer - 修改必须在协程启动前执行,即
Co\run()或go()之前,否则无效
为什么局部变量不会自动释放?和栈空间有关吗?
无关。局部变量生命周期由 PHP 引用计数管理,协程结束时会正常析构;真正危险的是静态变量、全局变量、$_SERVER 等超全局数组的引用——它们绑定在 Worker 进程全局作用域,**栈空间再大也救不了泄漏**。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 典型陷阱:
static $cache = [];在onRequest中不断$cache[$key] = $bigData;,协程退出后数组仍在 - 协程栈只存执行上下文(寄存器、返回地址、局部变量值),不存静态/全局数据本身
- 栈溢出 ≠ 内存泄漏,前者是瞬时崩溃,后者是缓慢增长、难以察觉
如何验证当前协程栈使用量?
没有内置函数直接返回已用栈大小,但可通过 Swoole\Coroutine::stats() 查看当前 Worker 内协程总数与内存占用趋势,再结合 strace -e trace=brk,mmap,clone 观察系统调用行为辅助判断。
-
Swoole\Coroutine::stats()返回['coroutine_num' => 123, 'coroutine_peak_num' => 245],若coroutine_peak_num持续逼近coroutine_num,说明存在协程堆积,可能因未释放 channel 或阻塞在未 hook 的 IO 上 - 真实栈压测:写一个递归函数
function boom($n) { return $n ? boom($n-1) : 0; },在协程里调用并逐步增大$n,观察崩溃点 - 关键信号:出现
coroutine stack overflow后,该协程立即终止,但 Worker 进程不会退出,后续请求仍可处理
栈空间配置是个窄窗口:太小崩得快,太大撑得慢;真正难防的是静态变量在常驻进程里悄悄膨胀——它不占栈,但比栈溢出更难定位。

















