系统相关
首页 > 系统相关> > Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架

Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架

作者:互联网

image

Memlab 是一款 E2E 测试和分析框架,用于发现 JavaScript 内存泄漏和优化机会。

MemlabJavaScript 的内存测试框架。它支持定义一个测试场景(使用 Puppeteer API),教 Memlab 如何与您的单页应用程序(SPA)交互,Memlab 可以自动处理其余的内存泄漏检查:

安装 Memlab

npm install -g memlab
memlab help

在 Demo App 中检测泄漏

使用 Memlab 检测分离的 DOM 元素的教程。Demo 源码:

设置示例 Web App

当您单击 “Create detached DOMs” 按钮时,Demo app 会泄漏分离的 DOM 元素。每次单击都会创建 1024 个分离的 DOM 元素,这些元素由 window 对象引用。

image

// @nolint

import Link from 'next/link';
import React from 'react';

export default function DetachedDom() {

  const addNewItem = () => {
    if (!window.leakedObjects) {
      window.leakedObjects = [];
    }
    for (let i = 0; i < 1024; i++) {
      window.leakedObjects.push(document.createElement('div'));
    }
    console.log('Detached DOMs are created. Please check Memory tab in devtools')
  };

  return (
    <div className="container">
      <div className="row">
        <Link href="/">Go back</Link>
      </div>
      <br />
      <div className="row">
        <button type="button" className="btn" onClick={addNewItem}>
          Create detached DOMs
        </button>
      </div>
    </div>
  );
}

源文件:packages/e2e/static/example/pages/examples/detached-dom.jsx

1. 克隆仓库

要在本地机器上运行 demo,请克隆 memlab github 存储库

git clone git@github.com:facebookincubator/memlab.git

2. 运行示例 App

从 Memlab 项目的根目录运行以下命令:

cd packages/e2e/static/example
npm install
npm run dev

这将启动一个示例 Nextjs app。让我们通过从浏览器访问 http://localhost:3000 来确保它正在运行:

image

这里测试的是 Example 1

查找内存泄漏

1.创建一个场景文件

// @nolint
// memlab/packages/e2e/static/example/scenario/detached-dom.js
/**
 * 我们要运行的场景的初始 `url`。
 */
function url() {
  return "http://localhost:3000/examples/detached-dom";
}

/**
 * 指定 memlab 应如何执行您要测试该 action 是否导致内存泄漏的 action。
 *
 * @param page - Puppeteer's page object:
 * https://pptr.dev/api/puppeteer.page/
 */
async function action(page) {
  const elements = await page.$x(
    "//button[contains(., 'Create detached DOMs')]"
  );
  const [button] = elements;
  if (button) {
    await button.click();
  }
  // 从 memlab 清理外部引用
  await Promise.all(elements.map(e => e.dispose()));
}

/**
 * 指定 memlab 应如何执行将重置您在上面执行的 action 的 action。
 *
 * @param page - Puppeteer's page object:
 * https://pptr.dev/api/puppeteer.page/
 */
async function back(page) {
  await page.click('a[href="/"]');
}

module.exports = { action, back, url };

这个文件在 packages/e2e/static/example/scenario/detached-dom.js

2.运行 memlab

这可能需要几分钟:

cd packages/e2e/static/example
npm run dev # 注意启动 Demo
memlab run --scenario scenarios/detached-dom.js

image

3.调试泄漏跟踪

对于每个泄漏的对象组,memLab 打印一个具有代表性的泄漏跟踪。

image

让我们从上到下分解结果:

第 1 部分:浏览器交互面包屑显示了按照我们的场景文件中指定的方式执行的浏览器交互(导航)memlab

第 2 部分:泄漏跟踪的总体摘要

第 3 部分:每个泄漏簇的详细代表泄漏跟踪

泄漏跟踪是从 GC 根(垃圾收集器遍历堆的堆图中的入口对象)到泄漏对象的对象引用链。跟踪显示泄漏的对象为何以及如何在内存中仍然保持活动状态。 打破引用链意味着泄漏的对象将不再可以从 GC 根访问,因此可以进行垃圾回收。

通过从原生 Window(即 GC 根)向下逐个跟踪泄漏跟踪,您将能够找到应该设置为 null 的引用(但这不是由于bug 引起的)。

简而言之,从 Window 对象到泄漏对象的泄漏跟踪路径为:

[window](object) -> leakedObjects(property) -> [Array](object)
  -> 0(element) -> [Detached HTMLDIVElement](native)

与示例中的泄漏代码匹配:

window.leakedObjects = [];
for (let i = 0; i < 1024; i++) {
    window.leakedObjects.push(document.createElement('div'));
}

更多

标签:Node,泄漏,leakedObjects,Memlab,JavaScript,js,内存,memlab,page
来源: https://www.cnblogs.com/hacker-linner/p/16701248.html