JavaScript高级:垃圾回收机制

1 引言

垃圾回收机制(Garbage Collection)简称 GC。js中的内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。

 

 2 内存的生命周期

js环境中分配的内存,一般有如下的生命周期:

1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为它们分配内存;

2. 内存使用:即读写内存,也就是使用变量、函数等;

3. 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存;

说明:

1. 全局变量一般不会回收(关闭页面才会被回收);

2. 一般情况下局部变量的值,不被使用了,会自动被回收;

3. 程序中分配的内存 由于某种原因,程序未释放或无法释放叫做内存泄漏;(1.下面会提到两个对象相互引用会造成内存泄漏;2. 闭包的一个缺点就是会造成内存泄漏)

3 垃圾回收机制的算法说明

3.1 堆栈空间分配的区别

1. 栈(操作系统):由于操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放到栈里面;

2. 堆(操作系统):一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收复杂数据类型放到堆里面;

3.2 常见浏览器的垃圾回收算法

3.2.1 引用计数算法

IE 浏览器采用的是引用计数算法,定义 “内存不再使用”, 就是看一个对象是否有指向它的引用,没有被引用了,就回收。

3.2.1.1 算法思路

1. 跟踪记录被引用的次数;

2. 如果被引用了一次,那么记录次数就为1, 多次被引用, 则++;

3. 如果减少一个引用就减一, -- ;

4. 如果引用次数是0, 则释放内存;

3.2.1.2 绘图说明

代码示例1:

const arr = [1, 2, 3]
arr = null

数组是复杂数据类型,所以在栈中存的是地址,arr 通过栈中的地址找到堆中的 [1, 2, 3]

<1>. 当执行第一行代码时:

<2>. 当执行第二行代码时:

此时arr被赋值null, null数简单数据类型, 存在栈中

<3>. 被引用次数为0,就会自动被回收了


代码示例2;

let person = {
      name: '张三',
      age: 18
}
let person2 = person
person = 1
person = null

<1>. 代码从上往下执行,对象是复杂数据类型,栈中存地址,堆中存的是数据:

 

<2>. 当代码执行到 let person2 = person 时

将person赋值给person2, 但是复杂数据类型赋的是地址, 所以此时 perosn2 与 person指向相同的地址, 所以person 和 person2指向堆中相同的数据,引用次数变为了 2

<3>.当执行 person = 1 时

 此时person被1赋值, 1属于简单数据类型,存在栈中, 地址改变了,找不到堆中的数据了,所以引用次数减 1

<4>.当执行person2 = null 时

跟上面一样,person2被赋值了简单的数据类型,不再指向堆中的数据,被引用次数再次减去1, 变为了0 此时堆中的数据没有被引用了, 会被系统自动回收

3.2.1.3 引用计数法存在的问题

嵌套(循环)引用问题

代码示例:

function fn(){
   let obj1 = {}
   let obj2 = {}

   obj1.a = obj2
   obj2.a = obj1

   return '引用次数无法回收!'
}

fn()

<1>.当执行        let obj1 = {}
                          let obj2 = {}     这两行代码时,按道理,函数作用域内属于局部作用域,使用完,会被系统回收,


<2>. 但是出现了这两行代码, 问题就出现了,   obj1.a = obj2
                                                                             obj2.a = obj1

所以,如果两个对象相互引用,尽管它们已不再被使用,垃圾回收器也不会进行回收,就会导致内存泄漏

3.2.2 标记清除法

算法思想:

1. 标记清除法将 “不再引用的对象” 定义为 “无法到达的对象”

2. 就是从根部(在JS中就是从全局对象)出发定时扫描内存中的对象,反是能从根部到达的对象,都是还需要使用的

3. 那些无法从根部出发而触及到的对象被标记为不再使用的,稍后进行回收


所以,标记清除法 解决了引用计数法的嵌套引用的问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小蟹呀^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值