当前位置: 首页 > news >正文

React 闭包内存泄漏验证

React 闭包内存泄漏验证

先看问题代码

// 模块级注册表,生命周期 = 整个应用运行期
const callbackRegistry: Array<() => void> = []function MyComponent() {useEffect(() => {const payload = new LeakedPayload() // 10万元素的大对象const handler = () => console.log(payload.data.length)callbackRegistry.push(handler)//  没写 cleanup,handler 永远留在 registry 里}, [])
}

引用链:

callbackRegistry → handler(闭包) → payload → LeakedPayload

组件卸载了,callbackRegistry 引用 handlerhandler 闭包又引用 payload。GC 不回收。


那 Promise 呢?

useEffect(() => {const payload = new LeakedPayload()fetch('/api').then(() => console.log(payload.data.length))
}, [])

Promise resolve 后,.then() 的回调执行完就没人引用了,GC 随时可以回收。

区别就一句话:闭包是不是被一个长期引用抓住了。


Heap Snapshot 验证

怎么操作

  1. 挂载组件,然后卸载
  2. DevTools → Memory → Heap Snapshot
  3. Class filter 搜 LeakedPayload
  4. 重复几次,看实例数是不是只涨不跌
  5. 清空注册表,再拍一次快照,实例应该消失

实测结果

Heap Snapshot 对比

快照 操作 LeakedPayload 实例数
1 挂载 → 卸载 +1
2 挂载 → 卸载 +1(累计 2)
3 挂载 → 卸载 +1(累计 3)
4 清空注册表 全没了

点开实例,Retainers 会显示:

LeakedPayload← payload (闭包变量)← handler ()← callbackRegistry (模块作用域的数组)

修复

useEffect(() => {const payload = new LeakedPayload()const handler = () => console.log(payload.data.length)callbackRegistry.push(handler)// FIXED: cleanup 把引用断开return () => {const idx = callbackRegistry.indexOf(handler)if (idx > -1) callbackRegistry.splice(idx, 1)}
}, [])

被外部持有的引用,cleanup 时都得释放。


现实中类似的坑

WebSocket 回调

const wsManager = {listeners: new Map<string, (data: any) => void>(),on(event: string, cb: (data: any) => void) { this.listeners.set(event, cb) },off(event: string) { this.listeners.delete(event) },
}function ChatRoom({ roomId }: { roomId: string }) {const [messages, setMessages] = useState<Message[]>([])useEffect(() => {wsManager.on('message', (data) => {setMessages(prev => [...prev, data])})//  忘了 wsManager.off}, [roomId])
}

roomId 时,旧回调还赖在 wsManager.listeners 里,闭包里的 messages 被锁死。

Redux / Zustand 订阅

function UserPanel() {const [user, setUser] = useState<User | null>(null)useEffect(() => {store.subscribe((state) => {setUser(state.user)renderExpensiveProfile(state.user)})//  没有 unsubscribe}, [])
}

store 是全局单例,你往它身上挂回调,它就抓着不撒手。

埋点 SDK

analytics.onPageView((meta) => {trackWithPageContext(pageData, meta)
})function ReportPage() {const pageData = useFetchHugeReport()useEffect(() => {analytics.onPageView((meta) => {trackWithPageContext(pageData, meta)})}, [pageData])
}

pageData 每次变化都往 SDK 里塞新回调,旧回调带着旧数据赖着不走。

IntersectionObserver

function LazyImage({ src }: { src: string }) {const imgRef = useRef<HTMLImageElement>(null)useEffect(() => {const observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {loadImage(src).then(data => processImage(data))}})if (imgRef.current) observer.observe(imgRef.current)}, [])
}

Observer 内部也抓着回调闭包。记得 disconnect()


http://www.jsqmd.com/news/683008/

相关文章:

  • 从2.8s到197ms:C# .NET 11中AI模型推理延迟骤降93%的7个关键配置,第4条90%开发者仍在踩坑
  • wan2.1-vae开源大模型部署:基于Qwen-Image-2512的轻量化文生图技术栈
  • CST微波工作室新手避坑指南:边界条件和背景材料到底该怎么选?
  • Betaflight固件编译实战:从源码到飞控的完整指南
  • 别再手动导数据了!用HFSS脚本录制功能,5分钟搞定S参数批量导出(附Python脚本)
  • 别再为AI入门发愁了!手把手教你用华为云ModelArts搞定第一个图像识别模型(附数据集避坑指南)
  • CompressO:3分钟掌握开源视频压缩神器,释放硬盘空间不是梦
  • PVZ Toolkit:解锁植物大战僵尸无限可能,你的终极游戏辅助神器
  • 3月优质!市场有名的箱泵一体化消防泵站厂家深度评测,箱泵一体化消防泵站/不锈钢水箱,箱泵一体化消防泵站品牌怎么选 - 品牌推荐师
  • 计算机毕业设计:Python股票数据挖掘与LSTM股价预测平台 Flask框架 LSTM Keras 数据分析 可视化 深度学习 大数据 爬虫(建议收藏)✅
  • 从MySQL到Redis,聊聊那些用RocksDB做存储引擎的开源项目(附Pika、MyRocks实战)
  • AI 信源争夺战:深圳本地 GEO 优化公司的产业实践与技术破局 - 品牌评测官
  • 嵌入式老鸟的私房工具链:深度定制你的aarch64-linux-gnu-gcc(附性能调优技巧)
  • AI_03_大模型提示词工程基础
  • 手把手教你用网线搞定华为S5735S交换机堆叠(iStack实战,含版本检查与避坑点)
  • 2026年青少年厌学、休学、辍学问题解决机构推荐:浙江万树青少年心理健康咨询有限公司,提供多维度专业服务 - 品牌推荐官
  • Steam创意工坊下载终极方案:WorkshopDL三步掌握跨平台模组自由
  • 2026年上下推拉窗/断桥推拉窗/两轨推拉窗等各类推拉窗厂家推荐:云南沃客门窗有限公司,一站式服务值得信赖 - 品牌推荐官
  • 免费家庭KTV终极指南:UltraStar Deluxe完整使用手册
  • 别再到处找了!Windows电脑安装嘉立创EDA专业版(2.1.33版)最全图文指南
  • Docker沙箱安全基线崩塌预警:CVE-2023-28842后时代,必须立即执行的6项runc沙箱加固操作
  • 数据抓取落地指南
  • 别再只盯着语音芯片了!搞定嵌入式语音播报,功放电路选型与PCB布局才是关键
  • TwitchDropsMiner完整指南:三步实现零带宽自动获取游戏掉落
  • 2026年跨境服务机构推荐:北京中宁智创智能科技有限公司,提供农林牧渔、机械设备、化工及能源等多领域跨境服务 - 品牌推荐官
  • 埃及投资前景与商业价值深度解析
  • 2026年玻璃减薄液、AG玻璃等产品厂家推荐:肇庆市精尔美玻璃科技有限公司,适配多领域电子屏幕处理 - 品牌推荐官
  • [AI智能体选型] 2026企业落地必看:Agent在在非结构化数据处理方面表现最好的工具是哪个?实在Agent全场景技术解析
  • Boss-Key老板键:5分钟掌握专业级窗口隐私保护方案
  • 2026年镀锌方管、幕墙方管、Q355B方管等厂家推荐:西安兴宝晟钢铁有限公司,多种方管产品适配多领域应用 - 品牌推荐官