答案是泄漏源在php层外,需排查c扩展资源未释放、静态缓存未清空、循环引用未破除及容器常驻进程内存滞留;应手动销毁gd/curl/pdo资源,清理static缓存,并设置容器内存限制。

memory_get_usage(true) 持续上涨但容器 RSS 不回落,说明泄漏不在 PHP 脚本层,而在 Docker 容器生命周期内未释放的底层资源或扩展残留。
memory_get_usage(true) 显示增长但 docker stats RSS 不降,怎么办?
- 这不是 PHP GC 失效的问题,而是内存根本没还给操作系统:Zend 内存管理器(MM)会缓存已分配页供后续复用,
memory_get_usage()只反映 PHP 层“已申请”,不等于 OS 层“已占用” - 真正要盯的是
docker stats <container_id></container_id>输出的MEM USAGE列——如果它随时间单向爬升,才是真实泄漏 - 常见假象:
- CLI 脚本跑完后没退出进程(如 Swoole worker、Amp loop),内存被长期持有
-
php-fpm的pm.max_children配置过低,导致请求排队+连接堆积+内存缓存滞留 -
opcache.memory_consumption设得过大(如 512M),且opcache.validate_timestamps=0,重启前一直占着
Docker 容器里 PHP 扩展资源必须手动销毁
PHP 不会自动释放三类 C 层资源,它们直接映射到系统 malloc,Zend MM 不接管:
-
GD图像资源:必须调用imagedestroy($img),否则10MBPNG =10MBRSS 持久占用 -
PDOStatement或游标结果集:执行$stmt->closeCursor()或设$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false)防全量加载 -
cURL句柄:不用时立刻curl_close($ch);若复用,确保CURLOPT_RETURNTRANSFER开启,避免输出直接刷屏导致缓冲区膨胀 - Redis/AMQP 等扩展客户端:不能只
unset($client),要显式调$client->__destruct()或$client->quit()(依扩展而定)
gc_collect_cycles() 在 Docker 中基本无效,别依赖它
- 它只清理 PHP 层循环引用,对 C 扩展分配的内存、mmap 区域、静态全局变量完全无感
- 在常驻进程(如
swoole_http_server)中,gc_collect_cycles()返回值 > 0 仅说明有 PHP 对象被回收,不代表 RSS 下降 - 更危险的是:频繁调用它反而干扰 Zend MM 的页合并策略,可能加剧内存碎片
- 正确做法是:
- 用
debug_zval_dump($var)查refcount__gc,确认对象是否真被孤立 - 对关键对象(如
DOMDocument、XMLReader)手动调$obj->clear()或unset($obj)后立即gc_collect_cycles() - 在 Swoole
onWorkerStart里清空静态缓存:self::$cache = [];
- 用
docker run 启动时必须加内存限制和 OOM 行为控制
不设限的容器在泄漏发生时会吃光宿主机内存,触发 kernel OOM killer 杀错进程:
- 启动时强制限制:
docker run --memory=512m --memory-swap=512m --oom-kill-disable=false ... - 配合
--restart=on-failure:3,让泄漏崩溃后自动重启,避免僵死 - 在
Dockerfile中禁用无意义缓存:ENV ZEND_MM_ALLOC_LARGE_PAGES=0 ENV ZEND_MM_DEBUG=0
- 生产镜像里删掉
xdebug.so和opcache.enable_cli=1,CLI 模式下 Xdebug 会显著拖慢 GC 并放大内存观测误差
真正卡住内存的,从来不是没 unset 的数组,而是你忘了 imagedestroy() 的那张图、没 closeCursor() 的那个 PDOStatement、或者 Swoole worker 里越攒越多的 static::$logBuffer。Docker 不会帮你兜底,它只负责把泄漏打包运行得更稳——稳到你发现不了问题,直到 OOM killer 突然敲门。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











