使用DevTools进行网页内存分析
==================

#### 开启DevTools

DevTools为Chrome浏览器自带工具，[下载](https://www.google.com.hk/intl/en_uk/chrome/)并启动Chrome浏览器后，在需要进行内存分析的页面按下F12或者Shift+Ctrl+I启动DevTools开发者工具。

#### 获取js堆内存快照

在内存界面下选择堆快照，点击获取快照即可对当前页面进行一次内存快照。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/4e/v3/um_lZ9F3R2WvchnXVGnpUQ/zh-cn_image_0000002634010144.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=92B1161C87BA6E5B14F172C9B9A8FDAAACAE4F337CF738CB71E5A2030C5BFA21)

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a/v3/SLCZTLVkRYuS7PKfy6PeoQ/zh-cn_image_0000002664209293.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=37C343FFA33ADD328B5FB80DC1DA60C062342532711EEFA84B2D0F2A48C595B8)

#### 堆快照分析

#### \[h2\]摘要(Summary)

摘要展示当前内存快照的概览。其中：

*   构造函数(Constructor):表示对象的构造器
*   距离(Distance):与GCroot的引用链距离。当出现同一类对象距离不同的情况，要注意代码逻辑可能出现问题。
*   对象计数(Object Count)：跟在构造器后方的灰色数字，表示当前构造器所构造的对象总数。
*   浅层大小(Shallow Size)：对象自身占用的内存大小。
*   保留大小(Retained Size)：当一个对象被释放后，系统虚拟机可以释放的总内存。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/99/v3/cSpFLUfnSaqbEthrYdcDCA/zh-cn_image_0000002664329353.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=625F20A8CC78830164CC3F71704359B4445024343DCFFA81903219DB1601D9EC)

在摘要界面的右侧有一个选择栏，用户可以选择查看特定的对象，例如下图中选择“在快照2和快照3之间分配的对象”，这样生成的摘要可以用于定位内存问题发生的位置。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e5/v3/ndMSd_5_T4magdICxueCSQ/zh-cn_image_0000002633850242.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=E804350657764A5BDA2C671B3E064BEB804365F41752B10291161D0BC4446744)

#### \[h2\]比较(Comparison)

在比较(Comparison)中可以将当前快照与另一个快照比较，跟踪对象属性和内存占用的变化。其中：

*   构造函数：对象的构造器。
*   新对象数(New)：该对象构造器下有多少新的对象被创建。
*   已销毁(Deleted)：该对象构造器下有多少新对象被销毁。
*   增量(Delta)：新对象与被删除对象的差值。
*   分配大小(Alloc Size)：两份快照间分配的内存大小。
*   已释放大小(Freed Size)：两份快照间释放的内存大小。
*   大小增量(Size Delta)：分配大小和已释放大小的差值。

可以根据比较界面不同快照间的差异分析内存问题。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/80/v3/Jyke0BR8SSCpHrLqsRD6ug/zh-cn_image_0000002634010146.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=697D6737A5406E0DA288EB3961799446D27DD3E2CD56E8A4B8EFEFB0848AD790)

#### \[h2\]控制(Containment)

控制(Containment)提供了一个自上而下的树形界面，该界面允许浏览和探索堆内存中的内容。我们可以用它来分析任意变量的引用情况。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/98/v3/mJOD1Xr5Qdabjkbeh4tCnw/zh-cn_image_0000002664209295.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=38C0B1E92453793FD687198E01F4B7A8D4C518B9E09C7C20868825FC58D978BF)

#### \[h2\]统计信息(Statistics)

统计信息(Statistics)用一个饼图展示各个类型对象的内存占用比例。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/60/v3/LCXk3zuWQ1ixMulMe04sLw/zh-cn_image_0000002664329355.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=3FD7EC2B121A76C00FFAC8CF80956023D992FEC46D6386CA7AD335A407BE6C43)

#### 内存泄漏分析流程

1.  打开一个可能存在内存泄漏问题的页面并启用DevTools。下图展示的页面来自GitHub上的[memory-leak-simulation](https://github.com/Buchatech/JavaScript-Memory-Leak-Simulation)项目，该网页通过设置全局数组并不断向其推入'memory leak'字符串来模拟内存泄漏场景。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e2/v3/pYm5AhMDS-qbIj8qNqoqXA/zh-cn_image_0000002633850244.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=4A71677AB03135928A503524B8B7BE2B4E28C9A508FCA254081E281140365F8D)
    
2.  在性能界面录制可能导致内存泄漏的用户操作，以识别引起内存泄漏的用户操作或组件。下图显示，网页已加载完毕，但内存仍在持续上升，表明可能存在内存泄漏问题。对于包含大量动态组件和频繁DOM操作的网页，内存曲线可能呈起伏状态。持续观察内存起伏的最低值变化，若最低值逐渐上升，怀疑网页存在内存泄漏问题。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/10/v3/AQaCEWm-Tfy8hzZnbVJM3Q/zh-cn_image_0000002634010148.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=9D074B29CB7275A82B3AF5D87F4AB0F4519F92C39222B8F7223D5DEED92CCB14)
    
3.  我们对这个网页进行第一次堆快照，发现Array占用了28M内存，基于该对象的内存占用显著高于正常值(通常在几MB范围内)，可以判断该对象可能存在内存泄漏问题。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/cb/v3/RDULDZ5cSrKMsOxt7JqU9g/zh-cn_image_0000002664209297.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=0E84D62F5D0826A4F5F502D49C07762139CE07ABE7B255B33B5357FB3695000E)
    
4.  对网页进行可能会造成内存泄漏的操作，操作完成后进行第二次堆快照，然后选择两个快照间分配的对象，观察到Array构造器新产生约16MB内存占用。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/de/v3/k5yucLb6Sd2Z8p6SnmdPOQ/zh-cn_image_0000002664329357.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=5DA4DD687761ED3ED489DE71985C59B244E0F21A480D29B48C69E5405D881FB1)
    
5.  查看**比较(comparison)**，选择快照3并使用快照2作为比较对象，观察到Array构造器新产生了4030个对象，占用了16.1MB空间，但只释放了184B空间，根据此结果，确定内存泄漏发生在Array中。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/3b/v3/fkCGhFBkSCCmAghTwXcvlw/zh-cn_image_0000002633850246.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=047E06E484DCD54C1A5B59BF1CC1BF2BEB924A4651AEE9226231873C9B7472DA)
    
6.  录制1-2分钟的堆快照来获得包含时间轴的摘要视图，这与性能界面中的视图类似。使用此视图可以分析是哪个动作造成了内存占用的变化。录制快照时选择“时间轴上的分配情况”选项，点击录制。完成想要测试的动作后，停止录制即可生成内存堆时间轴视图。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/38/v3/xfucIF-1RM-ASXjq7rMDiw/zh-cn_image_0000002634010150.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=395AE957CD29A2219368F23E6461BACD5170CD16A2C4123014336EDA1A82ED37)
    
7.  在结果的时间轴上，使用左键滑动选择想要查看的区域，即可查看选定时间段内的内存分配情况。从下图中框选部分可以看到，在选定时间内，Array构造器产生了两千个新对象。利用该功能，可以明确不同操作对内存的影响。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/63/v3/_lVildFISPSq_jufVKCJLA/zh-cn_image_0000002664209299.png?HW-CC-KV=V1&HW-CC-Date=20260709T132823Z&HW-CC-Expire=86400&HW-CC-Sign=0A1386CF3DF5EED69BDFB45A143613BAB8568584EEBDD691114DB56AA215AD45)