NodeJs - Chrome内存分析工具使用

本文介绍了如何在Node.js环境中使用v8-profiler工具进行内存分析,包括创建快照、查看不同视图(如Summary、比较、包含和支配项)以及识别内存泄漏迹象,着重讲解了如何通过快照和视图分析找到导致内存泄漏的原因。
摘要由CSDN通过智能技术生成

一. 前期准备

我们下载好相关依赖:

npm i v8-profiler-next

测试代码:

const v8Profiler = require('v8-profiler-next')
const fs = require('fs')

function createArray () {
    const arr = [];
    for (let i = 0; i < 100000; i++) {
        arr.push({ index: i, value: `value-${i}` });
    }
    return arr;
}
let leakArr = [];

function run () {
    createArray();
    createArray();
    createArray();
    console.log('Arrays created');
    setInterval(() => {
        console.log('Interval');
        // 模拟内存泄漏,将一个对象添加到数组中
        for (let i = 0; i < 100000; i++) {
            leakArr.push({ index: i, value: `value-${i}` });
        }
    }, 1000);
}

run();

const snapshot = v8Profiler.takeSnapshot();
snapshot.export((err, result) => {
    fs.promises.writeFile(`${Date.now()}.heapsnapshot`, result);
    snapshot.delete()
})


setInterval(() => {
    const snapshot = v8Profiler.takeSnapshot();
    snapshot.export((err, result) => {
        fs.promises.writeFile(`${Date.now()}.heapsnapshot`, result);
        snapshot.delete()
    })
}, 10000);

运行之后,当前目录会生成下面多个snapshot文件(运行时间久一点,15秒左右就可以):
在这里插入图片描述

二. Chrome 内存分析工具使用

Chrome内存分析工具中,对于视图的查看分为4种:
在这里插入图片描述

2.1 查看快照

快照的查看种类还有:

  • Summary 视图:会显示按构造函数名称分组的对象。使用它可以根据按构造函数名称分组的类型找出对象(及其内存用量)。它对于跟踪 DOM 泄露特别有用。
  • 比较视图(重点):会显示两个快照之间的差异。可使用它来比较操作前后的两个(或更多)内存快照。通过检查已释放内存中的增量和引用计数,您可以确认是否存在内存泄漏及其原因。
  • 包含视图:允许探索堆内容。它可让您更好地查看对象结构,有助于分析全局命名空间 (window) 中引用的对象,从而找出导致其存在的原因。您可以使用它分析闭包并在较低级别深入了解您的对象。
  • 支配项视图:会显示支配项树,可用于查找累积点。 此视图有助于确认是否有对对象的意外引用仍然保留,以及删除/垃圾回收是否确实在正常运行。

2.2 使用案例

浏览器输入:chrome://inspect/#devices,如图,点击Open dedicated DevTools for Node
在这里插入图片描述
点击之后出现相关弹框,我们点击加载按钮,把我们生成的两个dump文件加载进去:
在这里插入图片描述
加载好后,如图:
在这里插入图片描述

一般内存泄漏,我们重点关注是否存在:只有新增对象,却没有删除项的类别。 如图:
在这里插入图片描述

这里我们看到Object对象几乎都是新增,新增了一百万个,那么几乎可以确认这些对象就是内存泄漏的点了,我们展开来看下它的内容有啥:
在这里插入图片描述

就是我们循环里面不停地给数组中增加的对象:
在这里插入图片描述
因为这个数组,它在setInterval这个函数中被引用,所以它永远不会被释放,从而模拟出内存泄漏甚至最终OOM的情形。

相关名词解释:

  • Constructor:构造函数,表示使用此构造函数创建的所有对象。
  • #New:表示在两个快照之间新创建的对象数量。这些对象在两个快照之间被分配了内存。
  • #Deleted:表示在两个快照之间被删除的对象数量。这些对象在两个快照之间释放了内存。
  • #Delta:表示在两个快照之间的内存变化量。它是新创建对象的内存减去已删除对象的内存。
  • Distance表示对象与根对象之间的距离。根对象是内存中的起点,而距离是指从根对象到特定对象的路径长度。较大的距离值表示对象与根对象之间的引用链更长。
  • Shallow Size:表示对象本身占用的内存大小不包括对象引用的其他对象的内存。
  • Retained Size:表示对象及其所有可达对象占用的内存大小。它包括对象本身的内存大小以及对象引用的其他对象的内存大小。
    Alloc Size:表示对象在内存中分配的总大小,包括对象本身的大小以及对象引用的其他对象的大小。这个值是对象在内存中实际占用的大小。
  • Freed Size:表示在两个快照之间释放的对象的总大小。这些对象在两个快照之间被删除或释放了内存。
  • Self Size:表示对象本身占用的内存大小,不包括对象引用的其他对象的内存。与Shallow Size类似,Self Size更常用于表示对象的实际占用大小。
  • Retainers:表示引用特定对象的其他对象的数量。这些对象保持对特定对象的引用,因此会阻止特定对象被垃圾回收。
  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zong_0915

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值