迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 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 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 JavaScript 中 use strict

发布时间:2024/03/20 浏览次数:56 分类:JavaScript

在本文中,学习 JavaScript 中的 use strict 特性。我们将通过不同的示例了解如何在 JavaScript 代码语句中创建和执行 use strict 关键字。

JavaScript 邮政编码验证

发布时间:2024/03/20 浏览次数:68 分类:JavaScript

在本文中,我们将学习如何使用正则表达式来验证邮政编码,使用 JavaScript 代码和不同的示例。

在 JavaScript 中为一个元素设置多个属性

发布时间:2024/03/19 浏览次数:187 分类:JavaScript

本教程向我们展示了如何使用 JavaScript 一次为一个元素设置多个属性。我们将使用 setAttribute() 方法将每个属性及其值添加到元素中,并使用 Object.keys() 和 forEach() 方法来获取对象键的数

扫一扫阅读全部技术教程

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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便