thinkphp 8.0 内存溢出主因是调试开启、日志全量写入、全量查询加载、session 文件锁及缓存未分离等默认行为在高负载下叠加累积;解决核心是切断内存堆积链:关调试与日志、改游标分页、session/缓存切 redis、非实时操作入队列。

ThinkPHP 8.0 出现内存溢出,根本原因不是框架“太重”,而是默认行为在高负载场景下持续累积内存——调试开启、日志全量写入、全量查询加载、Session 文件锁、缓存未分离等环节叠加,让单个请求轻松吃掉 200MB+。解决核心是“切断堆积链”,而非盲目调高 memory_limit。
关掉调试与日志输出
上线环境必须确保:
- app_debug = false(config/app.php)
- 日志级别设为 'error' 或直接禁用日志驱动
- 手动清空 runtime/log/ 下所有历史文件(避免启动时扫描耗内存)
- CLI 命令如队列消费可单独提内存:php -d "memory_limit=512M" think queue:work
改全量查询为流式处理
导出或遍历大量数据时,禁用 Db::select() 和 paginate():
- 优先用 Db::cursor()(TP8.0 内置游标,自动使用未缓冲查询)
- 次选用原生 PDO + yield 构建生成器,确保不预加载全部结果
- 避免在循环里反复调用 find(),改用 whereIn() 批量查
- 大列表分页不用 offset,改用基于 ID 的游标分页(如 WHERE id > ? ORDER BY id LIMIT 500)
Session 和缓存必须切 Redis
file 驱动在并发下会引发文件锁和内存滞留:
- Session 配置改为:'type' => 'redis', 'use_trans_id' => true
- 缓存统一显式指定 Redis:Cache::store('redis')->get('key'),禁用默认 file
- Redis key 加业务前缀和 TTL(例如 user:info:123:202608,TTL ≤ 3600)
非实时操作全部丢进队列
登录记录、消息推送、统计更新等同步执行会卡住 PHP-FPM worker:
- 控制器中只发任务:Queue::push(new SendNotifyJob($userId))
- 队列消费用独立进程运行:php think queue:work --daemon
- CLI 模式下单独设内存上限,不与 Web 请求争资源
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











