内存泄露与垃圾回收机制

一、内存泄露
不再使用的内存,没有及时被释放,机会造成内存泄露
二、垃圾回收机制
因为收回过程内存开销比较大,且堵塞其他操作,所以V8引擎会周期性的释放那些不再使用的变量,进而释放内存

  1. 全局变量:生命周期较长,直到卸载当前页面才会回收
  2. 局部变量:如函数内的变量(排除个别闭包),一旦函数执行完毕,该变量即会被回收
  3. 闭包:分为两种,一种是程序自动生成的闭包,会遵循局部变量规则,但手动生成的闭包,V8引擎不会自动回收,需要开发者人为的将变量置为null,才会被回收。后期单独讲解闭包
    三、方式
    主要分为两种,标记清除和引用计数
  4. 标记清除:
    变量进入执行上下文时,会打个进入环境的标记,当离开执行环境时,再打个离开环境的标记,在下一个回收周期内,会将离开执行环境的变量进行回收
  5. 引用计数:
    当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。如果同一个值又被赋给另一个变量,则该值的引用次数加 1。
    相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。如:
function fn() {
    var q = {}; // q 指向对象的引用次数为 1
    var a = q;  // q 指向对象的引用次数加 1,为 2
    var c = q;  // q 指向对象的引用次数再加 1,为 3
    var a = {}; // q 指向对象的引用次数减 1,为 2
}

这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为 0 的值所占用的内存,进而无法刚问引用次数为0的变量。
但该方式会存在一个bug,即循环引用的变量不会被回收,如:

function fn() {
    var q = {};  // q 指向对象的引用次数为 1
    var a = {};  // a 指向对象的引用次数为 1
    q.obj = a;  // a 指向对象的引用次数为 2
    a.obj = q;  // q 指向对象的引用次数为 2
}
fn();

即使fn已经执行完毕,理论上q和a应该会被回收,但由于引用次数不为0,就造成了不会被回收

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值