NodeJs - Chrome内存分析工具使用

NodeJs - Chrome内存分析工具使用

  • 一. 前期准备
  • 二. Chrome 内存分析工具使用
    • 2.1 查看快照
    • 2.2 使用案例

一. 前期准备

我们下载好相关依赖:

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秒左右就可以):
NodeJs - Chrome内存分析工具使用_第1张图片

二. Chrome 内存分析工具使用

Chrome内存分析工具中,对于视图的查看分为4种:
NodeJs - Chrome内存分析工具使用_第2张图片

2.1 查看快照

快照的查看种类还有:

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

2.2 使用案例

浏览器输入:chrome://inspect/#devices,如图,点击Open dedicated DevTools for Node
NodeJs - Chrome内存分析工具使用_第3张图片
点击之后出现相关弹框,我们点击加载按钮,把我们生成的两个dump文件加载进去:
NodeJs - Chrome内存分析工具使用_第4张图片
加载好后,如图:
NodeJs - Chrome内存分析工具使用_第5张图片

一般内存泄漏,我们重点关注是否存在:只有新增对象,却没有删除项的类别。 如图:
NodeJs - Chrome内存分析工具使用_第6张图片

这里我们看到Object对象几乎都是新增,新增了一百万个,那么几乎可以确认这些对象就是内存泄漏的点了,我们展开来看下它的内容有啥:
NodeJs - Chrome内存分析工具使用_第7张图片

就是我们循环里面不停地给数组中增加的对象:
NodeJs - Chrome内存分析工具使用_第8张图片
因为这个数组,它在setInterval这个函数中被引用,所以它永远不会被释放,从而模拟出内存泄漏甚至最终OOM的情形。

相关名词解释:

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

你可能感兴趣的:(chrome,性能优化,前端)