迹忆客 专注技术分享

当前位置:主页 > 学无止境 > WEB前端 > JavaScript >

JavaScript 内存泄漏检测

作者:迹忆客 最近更新:2024/03/20 浏览次数:

不再需要内存泄漏的内存没有返回到空闲内存池或操作系统。

在三种最常见的情况下可能会发生内存泄漏:意外全局变量忘记的回调或计时器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() 中提供参考,并在不再需要它们时直接调用删除该函数。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

用 jQuery 检查复选框是否被选中

发布时间:2024/03/24 浏览次数:102 分类:JavaScript

在本教程中学习 jQuery 检查复选框是否被选中的所有很酷的方法。我们展示了使用直接 DOM 操作、提取 JavaScript 属性的 jQuery 方法以及使用 jQuery 选择器的不同方法。你还将找到许多有用的

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便