凌晨两点内存泄漏排查全记录

一、凌晨两点,线上服务突然挂了

那天晚上我正睡得迷迷糊糊,手机连续震了好几下,群里炸了锅:线上接口大面积超时,监控面板上一片飘红。我爬起来一看,PHP-FPM 的进程数飙到了上限,每个 worker 的内存占用都异常偏高,日志里刷满了Allowed memory size of 134217728 bytes exhausted。得,内存泄漏,跑不掉了。

说实话,这种问题最磨人。不是一下子崩,而是慢慢把内存吃光,等到某个时刻集中爆发。今天就把我这次排查的完整过程写下来,希望能帮遇到类似问题的朋友少走点弯路。

二、先复现,再谈定位

排查内存泄漏,第一步永远是复现。我先把出问题的接口单独拉出来压测,用ab连续打了几百个请求,然后盯着 PHP-FPM 的进程内存看。果然,单个 worker 的内存从 30MB 一路涨到 100MB 多,而且请求结束后并没有降回去。这就基本坐实了:某个请求周期里,有对象一直没被释放。

为了更直观地观察,我写了个简单的监控脚本,把每个请求前后的内存差打出来:

<?php // 在入口文件开头记录基线 $baseline = memory_get_usage(); // ... 业务逻辑 ... // 在请求结束时对比 error_log('内存增量: ' . (memory_get_usage() - $baseline) . ' bytes'); ?>

跑了几轮之后,日志里能明显看到某些接口的内存增量异常大,而且每次请求都在涨。这就把排查范围缩小到了那几个接口上。

三、顺着调用链找元凶

锁定接口之后,我开始逐段检查代码。翻到一段处理批量导入的逻辑时,发现了一个很典型的坑:循环里不断往数组里塞数据,但数组本身没有清空,导致内存越积越多。类似这样:

<?php // 危险写法:循环里无限累积 $allRows = []; foreach ($fileData as $row) { $processed = processRow($row); // 处理完的数据 $allRows[] = $processed; // 全部攒在内存里 } // 直到循环结束才一次性处理,内存早就爆了 ?>

这种写法在数据量小的时候看不出问题,一旦文件里有几万行,内存就直线上升。修复思路很简单:边处理边释放,不要把所有中间结果都攒在内存里。改成流式处理,每处理完一行就写出去,然后及时清掉引用:

<?php // 安全写法:边读边处理,及时释放 $handle = fopen($filePath, 'r'); while (($row = fgetcsv($handle)) !== false) { $processed = processRow($row); writeToDb($processed); // 立即落库 unset($processed, $row); // 主动释放引用 } fclose($handle); ?>

改完之后再压测,内存增量明显平稳了,不再一路飙升。

四、还有两个容易忽略的坑

除了循环累积,还有两个地方也容易埋雷。一个是静态变量和单例。如果某个类用静态属性缓存了数据,又没做清理,那这些数据会一直活到进程结束。另一个是外部服务调用没超时,比如某个接口请求第三方 API,对方一直不返回,连接和缓冲区就一直占着内存。

排查的时候可以用memory_get_peak_usage()看峰值,再配合gc_collect_cycles()手动触发一次垃圾回收,对比回收前后的内存差,能帮你判断是不是循环引用导致的泄漏:

<?php $before = memory_get_usage(); gc_collect_cycles(); $after = memory_get_usage(); error_log('GC 回收内存: ' . ($before - $after) . ' bytes'); ?>

如果回收前后差得很多,说明代码里存在循环引用,需要检查对象之间的相互持有关系。

五、总结:内存问题要防在日常

这次故障从发现到解决,前后折腾了大半夜。回头想想,其实很多内存泄漏都是编码习惯问题:循环里不注意释放、静态变量乱缓存、外部调用不设超时。与其等线上报警再熬夜排查,不如在写代码的时候就多留个心眼。建议大家在测试环境就养成看内存曲线的习惯,把memory_get_usage()打点加到关键接口里,早发现早处理。

如果你也遇到过类似的内存泄漏问题,欢迎在评论区聊聊你的排查思路,咱们一起交流交流。

相关新闻

dirsearch绕过WAF的五个实战技巧:从UA伪装到网络出口配置

dirsearch绕过WAF的五个实战技巧:从UA伪装到网络出口配置

1. 先弄明白&#xff1a;dirsearch扫描为什么会被WAF拦1.1 一次目录扫描的典型困境做Web目录扫描的人&#xff0c;几乎都用过dirsearch&#xff0c;也几乎都被WAF教育过。我印象很深的一次授权测试&#xff1a;目标是一个带前置WAF的业务系统&#xff0c;我拿到授权后顺手跑了默…

2026/10/21 7:50:07 阅读更多 →
四旋翼ADRC姿态控制:从核心公式到调参实践

四旋翼ADRC姿态控制:从核心公式到调参实践

四旋翼的ADRC姿态控制&#xff0c;总给人一种“玄学调参”的错觉。我最早接触自抗扰控制时&#xff0c;也被满屏的扩张状态观测器、总扰动、带宽法这些名词劝退过&#xff0c;直到真正从标题里那条滚转通道的角加速度方程往下一层层拆&#xff0c;才觉得这事其实比想象中有意思…

2026/10/21 7:50:07 阅读更多 →
2026年新兴CI/CD测试工具全景:五大阵营与选型落地指南

2026年新兴CI/CD测试工具全景:五大阵营与选型落地指南

我在整理2026年新兴CI/CD测试工具全景报告时&#xff0c;最直观的感受是&#xff1a;工具赛道已经从一个“能跑通流水线”的时代&#xff0c;进入了“能让测试活动在流水线里被精确调配”的时代。这份报告不是为了罗列新名字&#xff0c;而是想回答一个更实际的问题&#xff1a…

2026/10/21 7:50:07 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →