当前位置:网站首页>js垃圾回收机制和内存泄漏
js垃圾回收机制和内存泄漏
2022-07-06 09:29:00 【社会你磊哥,命硬不弯腰】
js的垃圾回收机制
概述
JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
JS垃圾回收方式
JS执行环境中的垃圾回收器怎样才能检测哪块内存可以被回收有两种方式:标记清除(mark and sweep)、引用计数(reference counting)。
标记清除
大部分浏览器以此方式进行垃圾回收,当变量进入执行环境(函数中声明变量)的时候,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被删除的变量。标记方式不定,可以是某个特殊位的反转或维护一个列表等。
工作流程
- 垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。
- 去掉环境中的变量以及被环境中的变量引用的变量的标记。
- 再被加上标记的会被视为准备删除的变量。
- 垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
引用计数
这种方式常常会引起内存泄漏,低版本的IE使用这种方式。机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为0时就会被回收。
这种方式引起的内存泄漏典型的就是循环引用,具体的在下文会探讨。
工作流程
- 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。
- 同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.
- 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.
- 当引用次数变成0时,说明没办法访问这个值了。
- 当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存
内存泄漏
什么是内存泄漏
内存泄露是指当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池的现象。内存泄漏可能会导致应用程序卡顿或者崩溃。
导致内存泄漏的情况和解决方法
闭包使用不当引发的内存泄漏
window.onload = function outerFunction(){
var obj= document.getElementById("eleId");
obj.onclick = function innerfunction(){
console.log(obj.id);
}
}
这里给DOM节点上面绑定了一个事件,事件里面有对上面dom节点的引用,就算这个外部函数执行完毕,事件函数里面也有对obj的引用。所以他的内存就无法得到回收。
解决办法
//手动清除
window.onload = function outerFunction(){
var obj= document.getElementById("eleId");
obj.onclick = function (){
console.log(obj.id);
}
obj=null
}
//将事件处理函数定义在外部,解除闭包
function bindEvent()
{
var obj=document.createElement("XXX");
obj.onclick=onclickHandler;
}
function onclickHandler(){
//do something
}
循环引用
function sample(){
var a={
};
var b={
};
a.prop = b;
b.prop = a;
}
这里就是a和b相互引用产生的内存泄漏,对于标记清除没有影响,但对于引用计数却带来了很大的影响。它的引用会一直都是2
被遗忘的定时器或回调函数
var someResource = getData();
setInterval(function(){
var node = document.getElementById("Node");
if(node){
node.innerHTML = JSON.stringify(someResource);
}
},1000);
这样的代码很常见, 如果 id 为 Node 的元素从 DOM 中移除, 该定时器仍会存在, 同时, 因为回调函数中包含对 someResource 的引用, 定时器外面的 someResource 也不会被释放。
意外的全局变量引起的内存泄漏
在这就直接说解决办法,使用严格模式即可use strict
边栏推荐
- Solve the problem of intel12 generation core CPU [small core full, large core onlookers] (win11)
- Fdog series (4): use the QT framework to imitate QQ to realize the login interface, interface chapter.
- LeetCode 1566. Repeat the pattern with length m at least k times
- (multiple methods, need to continue to see) 7-11 go deep into the tiger's Den
- DS18B20数字温度计系统设计
- 7-8 likes (need to continue to improve)
- Fdog series (I): think about it. It's better to write a chat software. Then start with the imitation QQ registration page.
- CMake Error: Could not create named generator Visual Studio 16 2019解决方法
- Chapter 5 detailed explanation of consumer groups
- 视频压缩编码和音频压缩编码基本原理
猜你喜欢
第5章 NameNode和SecondaryNameNode
第5章 消费者组详解
Shell_ 03_ environment variable
LeetCode 1584. Minimum cost of connecting all points
Shell_ 07_ Functions and regular expressions
Chapter 1 overview of MapReduce
The most lost road I have ever walked through is the brain circuit of ByteDance programmers
Chapter 5 detailed explanation of consumer groups
Redis standalone startup
Shell_ 02_ Text three swordsman
随机推荐
CMake速成
Redis standalone startup
TypeScript基本操作
Record the error reason
Tencent interview algorithm question
CMake Error: Could not create named generator Visual Studio 16 2019解决方法
这116名学生,用3天时间复刻了字节跳动内部真实技术项目
Some instructions on whether to call destructor when QT window closes and application stops
@RestController、@Controller
JS encapsulates the method of array inversion -- Feng Hao's blog
Cmake error: could not create named generator visual studio 16 2019 solution
LeetCode 1584. Minimum cost of connecting all points
Shell_ 04_ Shell script
Fdog series (4): use the QT framework to imitate QQ to realize the login interface, interface chapter.
~85 transition
ffmpeg命令行使用
~78 radial gradient
第5章 消费者组详解
字节跳动新程序员成长秘诀:那些闪闪发光的宝藏mentor们
Codeforces Global Round 19