JavaScript中的垃圾回收机制

本文详细介绍了JavaScript中的垃圾回收机制,包括栈和堆的概念、执行上下文与作用域链、两种回收策略(标记清理和引用计数)、垃圾回收的执行时机,特别是Chrome V8引擎的分代回收策略和Scavenge算法,以及内存问题如内存泄漏和内存溢出的解决办法。文章还提到了ES6的WeakMap用于解决内存泄漏问题。
摘要由CSDN通过智能技术生成


前置知识

堆栈

什么是栈
栈其实是一种数据结构,有着先进后出,后进先出的特性,用生活中的事物来理解最形象的就是汉诺塔了。我们在栈中存储的数据就像汉诺塔的盘子一样,最先放进去在最下面,最后放入的盘子在最上面。我们想拿数据的时候,也需要从塔顶开始拿,也就是最后放入的开始,上面的拿完才能拿下面的。

下图可以看做有三个栈
请添加图片描述

简而言之,我们可以将栈理解为一个具有先进后出,后进先出特点的存储空间,对于JavaScript来说,它会把基本数据类型放入栈内存储。

什么是堆
当我们创建一个对象的时候,实际上会在堆空间开辟一个空间,我们声明的变量保存的其实是堆空间的地址
堆和栈
简而言之,堆空间是存放复杂数据类型的存储空间,我们通过变量存储的其实是这些数据在堆空间内的地址。

当我们将一个本来存有地址的变量设置为null时,本质上是将该变量与堆空间的联系斩断,但堆空间内仍存有之前的复杂数据类型。只有当垃圾回收机制执行时,才会将这些没有人引用的复杂数据类型销毁,释放出堆空间。

执行上下文与作用域链

执行上下文

在JavaScript中有三种上下文

  • 全局执行上下文:Global Code
    JavaScript代码开始运行的默认环境

  • 函数执行上下文:Function Code
    存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文。

  • Eval 函数执行上下文: 使用eval()执行代码,因为很少用所以本次不做讨论。

在JavaScript代码执行的过程中,默认进入的总是全局执行上下文,JavaScript会把其存入上下文栈中去,每当遇到定义的函数被执行,便会创建一个新的执行上下文,并将其存入上下文栈中去。

当一个函数执行完毕后,上下文栈会将其弹出,将上下文环境交还给上个函数。

作用域链

上下文栈会根据栈内的顺序形成一条作用域链,用来控制变量的访问。处于上层作用域链的函数内部无法访问下层作用域链的变量。

下层作用域链中的函数可以访问上层作用域链的对象,若上层也没有,则再向上查找,直到全局作用域也没有,则返回null。

一、JavaScript中怎么被定义为垃圾

使用局部变量

function makeTrash(){
   
	var a = 1;
}
// 在makeTrash执行时,会创建a这个变量。
// 此时栈空间会为其分配一块区域供其存储。
makeTrash();
// 函数执行完后,由于不再需要变量a,所以此时的a便成为了垃圾
// 栈空间将会释放之前为a分配的空间。
// 至此,垃圾回收完毕

使用对象

// 此时的obj指向堆内存中创建的一块空间
var obj = {
   
	name:'ZhangSan',
	age:'18'
}

obj = null
// 当我们对其赋值为null的时候,obj与堆内存中的空间的关系被斩断。
// 由于堆内存中的空间没有人引用,所以这块空间就成了JavaScript中所谓的的垃圾

概括

凡是未被引用的变量或对象,都会被视为垃圾。

可能成为垃圾的特例
全局变量
由于全局对象window的销毁一般发生在页面卸载时,所以对于全局变量是否为垃圾很难进行判断,所以要尽量少用全局变量,或在用完设置

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值