JavaScript 内存泄漏检测
不再需要内存泄漏的内存没有返回到空闲内存池或操作系统。
在三种最常见的情况下可能会发生内存泄漏:意外全局变量
、忘记的回调或计时器
和 DOM 引用不足
。
JavaScript 中的 意外全局变量
内存泄漏
意外全局变量
未声明为全局
变量。垃圾收集器无法收集它们,从而导致内存泄漏。
name
变量被创建为全局 window.name
,它分配的空间永远不会被释放。
function fn1() {
// `name` is not declared
name = new Array(99999999)
}
fn1();
使用使用严格;
避免 JavaScript 中的内存泄漏
function fn1() {
'use strict';
name = new Array(99999999)
}
fn1();
输出:
未使用
变量未使用,需要删除或正确处理以释放内存空间。
最关键的一点是找到不再需要的内存。
JavaScript 使用垃圾收集器来确定代码的某个部分是否需要内存。
许多垃圾收集器使用 mark-and-sweep 算法。
使用"use strict";
来避免 JavaScript 中的全局变量引起的内存泄漏
在 Chrome DevTools 的 Memory
标签页上使用 heap allocations
。
你可以通过按 F12 或转到 Right Click
-> Inspect
-> Memory
在 Chrome 中打开 DevTools。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="leak-button">Start</button>
<button id="stop-leak">Stop</button>
<script>
var x=[];
var running = false;
function grow(){
x.push(new Array(1000000).join('x'));
if(running)
setTimeout(grow,1000);
}
$('#leak-button').click(function(){
running = true;
grow();
});
$('#stop-button').click(function(){
running = false;
});
</script>
</body>
</html>
输出:
在这里,每当用户单击开始
按钮并将包含百万个 x
字符的字符串推送到数组中时,脚本都会将 10.000
节点附加到 DOM
。
即使在按下停止
按钮后,垂直的部分蓝线也显示内存泄漏。
变量 x
是内存泄漏的原因,因为它是一个全局变量,即使不再需要它也会占用空间。
使用 {once: true}
和 removeEventListener()
避免 JavaScript 中的 DOM 引用不足导致的内存泄漏
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<button id="trigger">Trigger</button>
<script>
var clickElement = document.getElementById("click");
const hugeString = new Array(100000).join('x');
clickElement.addEventListener("click", function(){
// hugeString is kept in the scope of callback forever
document.write(hugeString);
});
</script>
</body>
</html>
输出:
活动的事件
侦听器可以防止变量被垃圾收集。
使用 removeEventListener()
或将第三个参数作为 {once: true}
传递。
这样,执行一次。listener
方法将被自动删除。
Forgotten Callbacks or Timer
引起的内存泄漏及其预防技术
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
for (var i = 0; i < 100000; i++) {
var obj = {
call_again: function() {
var message = this;
var value = setTimeout(function() {
message.callAgain();
}, 100000);
}
}
obj.call_again();
obj = null;
}
</script>
</body>>
</html>
输出:
timer callback
和它的绑定对象 obj
直到超时结束才被释放。
timer
可以自行重置并永远执行。因此,内存空间将始终保留,永远不会空闲。
在 JavaScript 中如何避免被遗忘的回调或计时器
通过在 setTimeout()
或 setInterval()
中提供参考,并在不再需要它们时直接调用删除该函数。
相关文章
在 JavaScript 中 use strict
发布时间:2024/03/20 浏览次数:56 分类:JavaScript
-
在本文中,学习 JavaScript 中的 use strict 特性。我们将通过不同的示例了解如何在 JavaScript 代码语句中创建和执行 use strict 关键字。
在 JavaScript 中验证表单输入中的数字
发布时间:2024/03/20 浏览次数:147 分类:JavaScript
-
本文将教你如何在 JavaScript 中验证数字。我们将使用正则表达式和 JavaScript 函数,包括 isNaN、parseFloat 和 isFinite。
JavaScript 邮政编码验证
发布时间:2024/03/20 浏览次数:68 分类:JavaScript
-
在本文中,我们将学习如何使用正则表达式来验证邮政编码,使用 JavaScript 代码和不同的示例。
在 JavaScript 中为一个元素设置多个属性
发布时间:2024/03/19 浏览次数:187 分类:JavaScript
-
本教程向我们展示了如何使用 JavaScript 一次为一个元素设置多个属性。我们将使用 setAttribute() 方法将每个属性及其值添加到元素中,并使用 Object.keys() 和 forEach() 方法来获取对象键的数
HTML Script Type 属性的使用
发布时间:2024/03/19 浏览次数:74 分类:JavaScript
-
本教程展示了 HTML5、HTML 4.01、XHTML 和 VBScripts 中 HTML 脚本类型属性的使用。
在 JavaScript 中使用 Onclick 转到 URL
发布时间:2024/03/19 浏览次数:129 分类:JavaScript
-
在今天的帖子中,我们将学习 JavaScript 中的 onclick 转到 URL。