确认存在swoole内存泄漏,需立即通过free -h观察available持续收窄、ps aux盯rss每分钟涨超50mb且10分钟不回落,并用任务管理器导出快照比对pid的rss差值超80mb;再验证swoole.so是否abi兼容php版本且ldd无缺失依赖;最后在业务代码中插入memory_get_usage打点并检查static累加、pdo未close等高频泄漏源。

宝塔面板中Swoole服务运行一段时间后内存持续上涨、重启PHP后短暂回落又快速攀升,且无明显并发增长或流量突增,说明可能存在Swoole扩展或业务代码引发的内存泄漏。必须跳过表层现象,直接切入进程级内存行为分析。
确认是否真为内存泄漏而非单纯高负载
执行free -h查看整体内存趋势,重点观察available列是否持续收窄;再运行watch -n 1 'ps aux --sort=-%mem | head -10'盯住RSS值——若某个php-fpm进程的RSS每分钟稳定增长50MB以上,且持续10分钟不回落,基本可判定为泄漏。
注意:仅看%MEM不准,因该值基于总内存计算,而泄漏进程RSS绝对值才是关键指标。
用宝塔任务管理器定位异常进程
登录宝塔面板 → 左侧菜单点击「软件商店」→ 搜索“任务管理器”→ 若未安装则点击安装,已安装但未启用则点击启动 → 安装完成后左侧菜单进入「任务管理器」。
进入后默认按CPU排序,点击顶部「内存」列标题两次,切换为**降序排列**,此时RSS值最高的进程即为首要嫌疑对象。
【务必检查CMD字段】:泄漏进程的CMD通常显示为php-fpm: pool www或php swoole_server.php,若看到php /www/wwwroot/xxx/start.php这类自定义入口,则泄漏极可能来自业务代码而非Swoole扩展本身。
比对快照确认RSS增长趋势
在任务管理器界面右上角点击「导出快照」→ 保存为snapshot_1.json → 等待5分钟后再次导出 → 保存为snapshot_2.json。
使用命令行比对两个快照中同一PID的RSS变化:jq '.processes[] | select(.pid == 12345) | .rss' snapshot_1.jsonjq '.processes[] | select(.pid == 12345) | .rss' snapshot_2.json
(将12345替换为实际PID)
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
若差值超过80MB,且该进程启动时间早于5分钟前,即可确认存在持续性内存增长。
验证Swoole扩展与PHP版本ABI兼容性
方法一:终端执行/www/server/php/82/bin/php --ri swoole | grep -E "(Version|compiled)",检查输出中「compiled」时间是否早于当前PHP 8.2安装时间;若编译时间明显更旧,说明扩展未适配当前PHP ABI。
方法二:直接运行ldd /www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/swoole.so | grep "not found",若有缺失依赖库(如libssl.so.1.1),说明扩展加载时已静默失败,后续所有内存行为均不可信。
这一步操作起来很简单,直接把命令复制粘贴进去回车就行,但结果必须为零报错才代表扩展真正生效。
检查业务代码中高频泄漏点
第一步:打开Swoole服务启动文件,在Server::start()前插入诊断钩子:swoole_async_set(['enable_coroutine_gc' => true]);Swoole\Coroutine::set(['hook_flags' => SWOOLE_HOOK_ALL]);
第二步:在onRequest回调开头加入内存打点:echo "[MEM] Start: " . memory_get_usage() . "\n";
在结尾加入:echo "[MEM] End: " . memory_get_usage() . "\n";
第三步:发起10次相同请求,观察日志中每次End值是否逐次递增——若第10次比第1次高3MB以上,说明请求间有资源未释放。
常见泄漏源:static数组累加、PDO连接未close、闭包持有了$this、Swoole\Table写入后未清理过期数据。










