- React Native虚拟DOM中类似于分离的文档对象模型 (DOM) 的对象。
- JavaScript对象中的循环引用。
- 保留了组件或事件侦听器以防止垃圾回收。
- 创建有意造成内存泄漏的适用于Vega的React Native应用示例。
- 在应用执行的不同阶段捕获堆快照。
- 使用MemLab分析这些快照并识别内存泄漏。
- 解读MemLab的输出以了解泄漏的性质和来源。
先决条件
- 安装Node.js。
-
安装Memlab:
-
使用调试VPKG版本配置您的环境以防止ANR崩溃,或者将以下内容添加到
react-native.config.js中:
步骤1:创建示例应用
出于测试目的,使用以下命令创建一个示例应用,其中存在故意造成的示例泄漏:示例app.js文件
以下文件示出了演示内存泄漏场景的示例应用的代码片段;并提供了创建、清除和分析内存泄漏的工具。步骤2:构建您的应用
运行以下命令:步骤3:运行应用
-
运行Vega虚拟设备。
-
在Vega虚拟设备上运行您的应用:
步骤4:捕获和复制堆快照
-
在拍摄每个快照之前,触发垃圾回收:
- 在应用运行时,单击Take Snapshot(拍摄快照)按钮以捕获设备上的堆快照。
- 选择Create Detached DOM Leak(创建分离的DOM泄漏)按钮以生成10,000个内存泄漏元素。
- 重新拍摄快照。
- 选择Clear Leaks(清除泄漏)按钮以移除模拟内存泄漏的元素。
-
拍摄最后的快照。
当您选择Take Snapshot按钮时,日志会显示系统保存快照文件的位置。
- 将快照文件复制到本地计算机。 使用拍摄的堆快照,可以分析和识别潜在的内存泄漏。
步骤5:运行MemLab
要在快照上运行MemLab,请使用以下命令格式。- 将所有快照加载到内存中。
- 比较基准和目标快照以识别新对象。
- 分析这些新对象在最终快照中的持久性。
- 跟踪对象引用以了解保留模式。
MemLab命令结构解释
memlab find-leaks命令是MemLab识别内存泄漏的核心功能。
以下参数是可选的:
- —baseline <初始快照> - 指定在引入任何潜在泄漏之前拍摄的初始堆快照。它可以作为参考点。
- —target <泄漏后快照> - 指定引入潜在泄漏后拍摄的快照。MemLab将快照与基准进行比较,以确定可能存在泄漏的新对象。
- —final <清除后快照> - 指定在尝试清除泄漏后拍摄的快照。它可以帮助MemLab确定对象是实际在泄漏还是只是处于一种正常应用状态。
--trace-all-objects- 指示MemLab跟踪所有对象,从而提供更全面的分析,但可能会增加处理时间。
MemLab输出示例
了解MemLab的输出
MemLab的输出包含以下关键元素。Alive objects allocated in the target page(在目标页面中分配的活动对象)
此部分显示应用操作或更改后仍存在于内存中的对象。此列表指出了潜在的内存保留问题,并包含每个对象的以下详细信息:name- 对象名称或其结构类型。type- 该对象是“对象”(如JSObject、JSArray等)还是“闭包”(保留内存的函数)。count- 每种对象类型的实例数。retainedSize- 这些对象保留的总内存。
JSArray (Object Type)- 305个实例,保留1.1MB的内存。JSObject(id, name)- 10,000个实例,也保留1.1MB的内存。
Sampling trace due to a large number of traces(由于大量跟踪而导致的采样跟踪)
本节显示,由于有10,100条跟踪,MemLab使用了49.5%的采样率来进行高效处理。MemLab found X leaks(MemLab发现了X个泄漏)
在示例中,MemLab发现了5个泄漏。对于每个内存泄漏,输出列出的内容包含:- 类似泄漏次数 - 该工具检测到类似泄漏模式的次数。
- 泄漏对象的保留大小 - 泄漏对象保留的总内存。
- 泄漏跟踪 - 对象的互连方式以及垃圾收集器无法收集它们的原因。
Garbage Collection (GC) roots(垃圾回收 [GC] 根目录)
这些根目录是保留在内存中的对象的入口点,并可防止其他对象遭遇垃圾回收 (GC)。该跟踪显示了GC根如何通过引用保持对象存活,路径可以追溯到JSObjects、JSArrays和闭包引用。 示例1 Leak pattern: 4,956 similar leaks, retaining 1.1MB of memory.JSObject(current) → JSArray → JSObject(id, name).
此跟踪表明JSArray保留了对10,000个JSObject(id, name) 对象的引用,以防止它们遭遇垃圾回收。
示例2
Leak pattern: 22 similar leaks, retaining 2.9KB of memory.
跟踪涉及Detached FiberNode RCTView对象,该对象是React Native视图系统的一部分。诸如onBlur之类的事件处理程序即使在代码删除了对象后也可能通过不必要地保留对象来造成泄漏。
使用MemLab分析快照
- 检查Alive objects allocated in target page部分以查看保留的对象。
-
查看MemLab found [X] leaks(MemLab发现 [X] 个泄漏)一行,看看MemLab发现了多少个不同的泄漏。
对于每个泄漏:
- 记下类似泄漏的数量和总保留大小。
- 检查物体跟踪以了解系统如何保留对象。
- 注意意外保留,例如分离的DOM元素或大型数组。
解决泄漏
您可以通过执行以下操作来解决应用中的泄漏问题:- 识别泄漏对象(例如,分离的DOM元素、未清除的事件侦听器)中的模式。
- 在您的应用中找到相应的代码。
- 实施修复,例如正确卸载组件、清除数组或删除事件侦听器。
验证修复
您可以通过执行以下操作来验证修复:- 使用已实施的修复重建并重新运行您的应用。
- 重复快照和分析过程。
- 确认先前发现的泄漏不再存在于MemLab输出中。

