当前位置:网站首页>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
边栏推荐
- Chapter 7__ consumer_ offsets topic
- LeetCode 1562. Find the latest group of size M
- LeetCode 1545. Find the k-th bit in the nth binary string
- Business system compatible database oracle/postgresql (opengauss) /mysql Trivia
- 第5章 消费者组详解
- 7-7 ring the stupid bell
- ~72 horizontal and vertical alignment of text
- Gridhome, a static site generator that novices must know
- Shell_ 02_ Text three swordsman
- LeetCode 1561. The maximum number of coins you can get
猜你喜欢
亮相Google I/O,字节跳动是这样应用Flutter的
LeetCode 1557. The minimum number of points that can reach all points
第7章 __consumer_offsets topic
两个礼拜速成软考中级软件设计师经验
Data config problem: the reference to entity 'useunicode' must end with ';' delimiter.
LeetCode 1637. The widest vertical area between two points without any point
Saw local status change event StatusChangeEvent [timestamp=1644048792587, current=DOWN, previous=UP]
ByteDance new programmer's growth secret: those glittering treasures mentors
Shell_ 05_ operator
SQL快速入门
随机推荐
Codeforces Global Round 19
Jedis
视频压缩编码和音频压缩编码基本原理
Chapter 6 datanode
Record the error reason: terminate called after throwing an instance
LeetCode 1637. The widest vertical area between two points without any point
~78 radial gradient
Codeforces Global Round 19
第一章 MapReduce概述
JS time function Daquan detailed explanation ----- AHAO blog
~68 Icon Font introduction
第7章 __consumer_offsets topic
~69 other ways to use icon fonts
SQL quick start
谢邀,人在工区,刚交代码,在下字节跳动实习生
How to generate six digit verification code
Solr word segmentation analysis
7-12 inventory code base
~76 sprite map
Spark independent cluster dynamic online and offline worker node