js垃圾回收

1.概念

JS会在创建变量时自动分配内存,在不使用的时候会自动周期性的释放内存,释放的过程就叫 “垃圾回收”。
优点:自动分配内存减轻了开发者的负担,开发者不用过多的去关注内存使
缺点:因为是自动回收,所以如果不清楚回收的机制,会很容易造成混乱,而混乱就很容易造成"内存泄漏".由于是自动回收,所以就存在一个 “内存是否需要被回收的” 的问题,

2.回收算法

2.1 标记清理

步骤

  • 1.变量进入上下文,会加上标记,证明其存在于该上下文;
  • 2.将所有在上下文中的变量以及上下文中被访问引用的变量标记去掉,表明这些变量活跃有用;
  • 3.在此之后再被加上标记的变量标记为准备删除的变量,因为上下文中的变量已经无法访问它们;
  • 4.执行内存清理,销毁带标记的所有非活跃值并回收之前被占用的内存;

优点

标记清除算法的优点只有一个,那就是实现比较简单,打标记也无非打与不打两种情况,这使得一位二进制位(0和1)就可以为其标记,非常简单

缺点

在清除之后,剩余的对象内存位置是不变的,也会导致空闲内存空间是不连续的,出现了 内存碎片,并且由于剩余空闲内存不是一整块,它是由不同大小内存组成的内存列表,这就牵扯出了内存分配的问题
在这里插入图片描述
在这里插入图片描述

补充:标记整理(Mark-Compact)算法

  • 它的标记阶段和标记清除算法没有什么不同,只是标记结束后,标记整理算法会将活着的对象向内存的一端移动,最后清理掉边界的内存
    在这里插入图片描述

2.2 引用计数

步骤

引用计数策略相对而言不常用,因为弊端较多。其思路是对每个值记录它被引用的次数,通过最后对次数的判断(引用数为0)来决定是否保留,具体的规则有

  • 1.声明一个变量,赋予它一个引用值时,计数+1;
  • 2.同一个值被赋予另外一个变量时,引用+1;
  • 3.保存对该值引用的变量被其他值覆盖,引用-1;
  • 4.引用为0,回收内存;

优点

引用计数算法的优点我们对比标记清除来看就会清晰很多,首先引用计数在引用值为 0 时,也就是在变成垃圾的那一刻就会被回收,所以它可以立即回收垃圾
而标记清除算法需要每隔一段时间进行一次,那在应用程序(JS脚本)运行过程中线程就必须要暂停去执行一段时间的 GC,另外,标记清除算法需要遍历堆里的活动以及非活动对象来清除,而引用计数则只需要在引用时计数就可以了

缺点(循环引用)

function refProblem () {
    let a = new Object();
    let b = new Object();
    a.c = b;
    b.c = a;  //互相引用
}

两个对象都互相引用了,引用计数不为0,所以两个变量都无法回收。如果频繁的调用改函数,则会造成很严重的内存泄漏。

3.常见的内存泄露

3.1意外声明全局变量

function hello (){
    name = 'tom'
}
hello();

未声明的对象会被绑定在全局对象上,就算不被使用了,也不会被回收,所以写代码的时候,一定要记得声明变量。

3.2定时器

let name = 'Tom';
setInterval(() => {
  console.log(name);
}, 100);

定时器的回调通过闭包引用了外部变量,如果定时器不清除,name会一直占用着内存,所以用定时器的时候最好明白自己需要哪些变量,检查定时器内部的变量,另外如果不用定时器了,记得及时清除定时器。

3.3 闭包

let out = function() {
  let name = 'Tom';
  return function () {
    console.log(name);
  }
}

由于闭包会常驻内存,在这个例子中,如果out一直存在,name就一直不会被清理,如果name值很大的时候,就会造成比较严重的内存泄漏。所以一定要慎重使用闭包。

3.4 事件监听

mounted() {
window.addEventListener("resize",  () => {
    //do something
});
}

在页面初始化时绑定了事件监听,但是在页面离开的时候未清除事监听,就会导致内存泄漏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值