React 16.8.6 版本存在内存泄露

发现这个React 内存泄露问题是某一天的晚上一直开着直播页,直播页用的 react 版本是 16.8.6,到了早上跳到这个页面的时候,控制台有点卡,怀疑是有内存泄露,因而就开始分析这个直播页面。node

分析

打开控制台 performance 面板点击开始录制,以下:react

从上图能够发如今这时间内, nodes 节点一直在增加,颇有可能发生了内存泄露。git

咱们来到 memory 面板分析内存变化:github

注:上图的蓝色线条表示在时间轴的最后该对象依旧存在,灰色线条则说明对象在时间轴内被分配,可是已经被gc(垃圾回收)了。数组

上图都是点击 gc 再进行记录的,可是上图还有不少蓝色线条,并且内存一直往上涨,很明显的内存泄露问题,那会是什么致使内存泄露的呢?app

很快发现这里有个 bi 的东西竟然占了 31%的大小: dom

这个 bi 是用来干吗的?展开 bi ,鼠标悬浮在 bi 某处:3d

发现这个节点是直播间里的进房消息,里面是 react 存的 FiberNode 节点,观察了一下里面这些 bi 基本上都是消息元素。code

选择 summary,选出Detached (分离)的元素:orm

Detached HTMLDivElement 竟然有41429个,展开,鼠标悬浮:

仍是消息信息,说明是这个致使 bi 增长的。咱们继续展开:

从上图看 react 会保留消息的上下兄弟节点的引用,并且保留的引用层级有点深,各个节点嵌套依赖,致使一直存在内存里:

仔细查下了项目消息相关代码,发现并不会存在有内存泄露的操做。这里简单说下渲染消息的逻辑,消息有进房消息,聊天消息,礼物消息等等,消息展现会根据 messages 数组里面的类型去渲染不一样的消息。messages 数组不会无限增加,控制在 100 个,超过就删掉第一个元素,保证维持100个元素渲染消息,可是从上图来看,这些分离的元素并无被 react 彻底删除,还保存在内存里,查了下 React 的 Issue,并查了相关文章,发现有很多人遇到这个问题:

React 核心成员 Dan 给出的解决办法是升级到 16.9.0。

这里将项目 React 和 React-dom 版本升级16.9.0, 发现 FiberNode 节点仍是会一直增长。。。

继续查看Issue 发现,React 版本 0.0.0-241c4467e 修复了这个问题。 Bug: Detached DOM node memory leak · Issue #18066 · facebook/react · GitHub

这个版本的 mr 已经合并在 React master 上 Null stateNode after unmount by bvaughn · Pull Request #17666 · facebook/react · GitHub

这个 mr 是 2019 年 12 月 20 号合并的,2019 年 12 月 20 号以后的版本是 16.13.0,这里将项目直接升级到 16.13.1,而后查看 node 节点:

发现 node 节点能够降下来了,查看 memory 面板:

对比Snapshot 5,分离的元素没有新增,说明这个版本基本修复了这个问题。

结论

React 16.8.6 (16.2.5到16.12.0 可能会有,这些版本没有验证,可是 issue 里面有人遇到)的版本会存在内存泄露问题,建议升级 React 到 16.13.0 以上。

相关文章
相关标签/搜索