内存泄漏以及如何使用 Chrome Dev Tools 查找它们

2025-06-04

内存泄漏以及如何使用 Chrome Dev Tools 查找它们

内存泄漏在应用程序中很难发现,可以通过在编写代码时采取一些预防措施来避免。每个开发人员都应该了解最常见的内存泄漏模式。

在本文中,我将尝试介绍应用程序中的内存生命周期模式、内存泄漏的最常见原因以及如何在 Chrome Dev Tools 中识别它们。

内存生命周期模式

内存生命周期模式表示为您的代码分配了一些内存分配的内存正在被您的代码使用,然后在执行您的代码时释放(释放)

替代文本

内存泄漏的原因

1. 意外的non-strict全局模式

function iCauseMemoryLeak() {
  temp = 1;
}
Enter fullscreen mode Exit fullscreen mode

这里,你给temp变量赋了一个在函数的任何作用域中都不可用的值iCauseMemoryLeak。JavaScript 编译器会将变量赋值到该global作用域中,并且该变量temp将来不会被垃圾回收。它会在你的应用程序生命周期中永远存在。

2. 被遗忘的计时器


setTimeout(() => {
  /** Perform a task here.. */
}, 1000);

// OR

setInterval(() => {
  /** Perform a task here.. */
}, 1000);
Enter fullscreen mode Exit fullscreen mode

计时器分配动态内存来执行任务,如果您忘记清除计时器,则会导致内存泄漏。

您可以清除setTimeout使用clearTimeoutsetInterval使用clearInterval


var a = setTimeout(() => {
  /** Perform a task here.. */
}, 1000);

clearTimeout(a);

// OR

var b = setInterval(() => {
  /** Perform a task here.. */
}, 1000);

clearInterval(b);
Enter fullscreen mode Exit fullscreen mode

3. DOM 操作

试想一下,您有两个按钮,当您单击buttonOne时,它​​将从DOM 中删除buttonTwo 。


const buttonOne = document.querySelector('#button-a');
const buttonTwo = document.querySelector('#button-b');

buttonOne.addEventListener('click', () => {
    document.body.removeChild(buttonTwo);
});
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,你buttonTwo通过点击 从 DOM 中移除buttonOne,但我们从未移除buttonTwo存储在变量 中的的引用buttonTwo。这种内存泄漏可能非常危险。

buttonTwo我们可以通过存储事件监听器内部的引用来避免这种情况click

const buttonOne = document.querySelector('#button-a');

buttonOne.addEventListener('click', () => {
    const buttonTwo = document.querySelector('#button-b');
    document.body.removeChild(buttonTwo);
});

Enter fullscreen mode Exit fullscreen mode

在这里,我们通过点击从DOMbuttonTwo删除,并将其作为垃圾收集buttonOne

Chrome 开发者工具中的识别

  • 打开 Chrome 开发工具。
  • 加载您的网站。
  • 在性能面板中选择“内存”复选框,然后单击“重新加载”图标。

替代文本

  • 加载配置文件和内存图表。

分析内存图

图片 A
替代文本

图片 B
替代文本

你觉得怎么样?哪张图片代表内存泄漏?

让我们按照内存生命周期模式来寻找答案

分配内存、使用内存和释放内存。

在图像 A,应用程序启动后会占用一些内存,然后释放,这种规律一直持续到应用程序处于加载状态。最终,当应用程序加载完成后,您会注意到图形几乎保持线性和平坦。这表明图像 A 中的应用程序在运行时需要预留内存,并且所需内存是恒定的。

另一方面,在图像 B中,内存图表始终在不断增加直到最后,它们是一个阶跃函数,这些图表表示内存随时间的增加。

现在,我们可以说图像 B代表内存泄漏。

希望你喜欢这篇文章。祝你学习愉快。

PS 你能猜出我在图像 A 中生成了哪个网站内存图吗?

参考:

  1. JavaScript 中的垃圾收集
  2. setTimeoutsetInterval
  3. Chrome 开发工具文档
文章来源:https://dev.to/ayusharma_/memory-leaks-and-how-to-find-them-using-chrome-dev-tools-2749
PREV
Redux 与 Context API
NEXT
为什么我从 Visual Studio Code 切换到 Vim