内存泄漏以及如何使用 Chrome Dev Tools 查找它们
内存泄漏在应用程序中很难发现,可以通过在编写代码时采取一些预防措施来避免。每个开发人员都应该了解最常见的内存泄漏模式。
在本文中,我将尝试介绍应用程序中的内存生命周期模式、内存泄漏的最常见原因以及如何在 Chrome Dev Tools 中识别它们。
内存生命周期模式
内存生命周期模式表示为您的代码分配了一些内存,分配的内存正在被您的代码使用,然后在执行您的代码时释放(释放)。
内存泄漏的原因
1. 意外的non-strict
全局模式
function iCauseMemoryLeak() {
temp = 1;
}
这里,你给temp
变量赋了一个在函数的任何作用域中都不可用的值iCauseMemoryLeak
。JavaScript 编译器会将变量赋值到该global
作用域中,并且该变量temp
将来不会被垃圾回收。它会在你的应用程序生命周期中永远存在。
2. 被遗忘的计时器
setTimeout(() => {
/** Perform a task here.. */
}, 1000);
// OR
setInterval(() => {
/** Perform a task here.. */
}, 1000);
计时器分配动态内存来执行任务,如果您忘记清除计时器,则会导致内存泄漏。
您可以清除setTimeout
使用clearTimeout
和setInterval
使用clearInterval
var a = setTimeout(() => {
/** Perform a task here.. */
}, 1000);
clearTimeout(a);
// OR
var b = setInterval(() => {
/** Perform a task here.. */
}, 1000);
clearInterval(b);
3. DOM 操作
试想一下,您有两个按钮,当您单击buttonOne时,它将从DOM 中删除buttonTwo 。
const buttonOne = document.querySelector('#button-a');
const buttonTwo = document.querySelector('#button-b');
buttonOne.addEventListener('click', () => {
document.body.removeChild(buttonTwo);
});
在上面的代码中,你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);
});
在这里,我们通过点击从DOMbuttonTwo
中删除,并将其作为垃圾收集。buttonOne
Chrome 开发者工具中的识别
- 打开 Chrome 开发工具。
- 加载您的网站。
- 在性能面板中选择“内存”复选框,然后单击“重新加载”图标。
- 加载配置文件和内存图表。
分析内存图
你觉得怎么样?哪张图片代表内存泄漏?
让我们按照内存生命周期模式来寻找答案。
分配内存、使用内存和释放内存。
在图像 A中,应用程序启动后会占用一些内存,然后释放,这种规律一直持续到应用程序处于加载状态。最终,当应用程序加载完成后,您会注意到图形几乎保持线性和平坦。这表明图像 A 中的应用程序在运行时需要预留内存,并且所需内存是恒定的。
另一方面,在图像 B中,内存图表始终在不断增加直到最后,它们是一个阶跃函数,这些图表表示内存随时间的增加。
现在,我们可以说图像 B代表内存泄漏。
希望你喜欢这篇文章。祝你学习愉快。
PS 你能猜出我在图像 A 中生成了哪个网站内存图吗?