你需要知道的JavaScript内存空间知识

我穿越了,文章写于2019-11-24。

前言

" 相信接触过Java、Python等后端语言的同学来说,内存空间是一个老生常谈的话题,但是作为前端开发的同学来说,这个并不会被经常提及,并且在日常编码中并不会注意一些细节问题。比如面试中常会问到的深拷贝与浅拷贝、按值传递和按引用传递等,如果从内存空间的角度去理解,会发现对你JS又有了更深的理解。 "

01 内存生命周期

在JS中,一般可以将内存分为两种:栈(包含池)、堆。其声明周期可以大概分为三个阶段:

  • 内存分配(声明)
  • 内存读写(使用)
  • 内存回收(销毁)

02 栈内存与基础数据类型

JS基础数据类型:Number、String、Boolean、Null、undefined、symbol、bigInt(自行了解)。

以上这些值都有固定大小,一般都保存在栈内存中,由系统分配固定的内存空间大小。我们在操作的时候直接操作内存中的值,即也就是在传递中是按值传递,遵循后进先出的原则进行读取。

需要强调的是,JS在执行过程中执行流进入一个函数时,会生成一个当前函数的执行环境(EC),并且推入到栈内存中,即我们所说的环境栈。所以JS在执行过程中消耗的是栈内存。

03 堆内存与引用数据类型

JS引用数据类型:Object、Array、Date、RegExp等。

引用数据类型的值时保存在堆内存中的对象,其内存空间大小是动态分配的。需要注意的是,JavaScript中不能直接访问堆内存中的位置,即不能直接操作对内存对象。而我们在平时操作引用数据类型的时候,其实操作的是这个对象的内存地址。相对应的,这个地址会被保存在栈内存中,形成一个映射关系。

举个例子:

js 复制代码
var a = { b: 1 }; 
var c = 100; 
function fn(a1, c1) { 
    a1.b = 1000; 
    a1 = null; 
    c1 = 200; 
} 
fn(a, c); 
console.log(a); 
console.log(c);

这是一道简单的题目,但是很好的表达了上面的堆栈原理。

答案是:{b: 1000}和100

当传递a的时候,实际上传递的是当前a对象的引用(地址)给了a1,其存储在栈内存中,执行a1.b = 1000进行修改的时,会通过这个地址去操作堆内存的对象,将b的值改为1000;接着a1 赋值为null,那么这时候a1就不会再指向堆内存,但是a的引用还是存在,所以对象变为修改后的{b: 1000},这就是所谓的按引用传递

而当传递实参c给形参c1的过程中,会把100直接复制新的一份给了c1,此时修改c1200后,实际上操作的就是c1这个变量,而不会影响原来的c,即该过程是按值传递。

04 内存回收

JavaScript中,自带有垃圾回收机制。其工作原理是会在每个固定时间执行一次内存释放操作,它内部有一套具体的回收机制,通过这个机制去找那些不再使用的值,回收对应内存。

标记清除法

这个是目前JavaScript最常用的垃圾收集方式。

请看下面代码

js 复制代码
var a = 100;
console.log(a + 10086);
a = null;

可以理解为当JS执行流进入这个环境的时候,会首先将a标记为"进入环境",当a离开环境时(a = null),则将其标记为"离开环境"。在垃圾收集器运行时,回收标记为"离开环境"的变量,释放内存。

引用计数法

这个是早期Netscape浏览器下一种不太常见的垃圾收集策略,由于这种方式不能回收循环引用的变量,导致对应内存不能被及时回收。后面放弃了这种方式,转而采用了标记清除来实现。

引用计数算法定义"内存不再使用"的标准很简单,就是看一个变量的引用次数是否为0。如果为0,说明该变量已经不再需要了。

综合以上,我们在日常开发中需要注意当变量不需要再使用的时候,请将其内存及时归还(赋值为null),特别是全局变量、定时器、DOM节点、闭包等等。

相关推荐
wearegogog1233 小时前
基于 MATLAB 的卡尔曼滤波器实现,用于消除噪声并估算信号
前端·算法·matlab
Drawing stars4 小时前
JAVA后端 前端 大模型应用 学习路线
java·前端·学习
品克缤4 小时前
Element UI MessageBox 增加第三个按钮(DOM Hack 方案)
前端·javascript·vue.js
小二·4 小时前
Python Web 开发进阶实战:性能压测与调优 —— Locust + Prometheus + Grafana 构建高并发可观测系统
前端·python·prometheus
小沐°4 小时前
vue-设置不同环境的打包和运行
前端·javascript·vue.js
qq_419854055 小时前
CSS动效
前端·javascript·css
烛阴5 小时前
3D字体TextGeometry
前端·webgl·three.js
桜吹雪5 小时前
markstream-vue实战踩坑笔记
前端
好好沉淀5 小时前
1.13草花互动面试
面试·职场和发展
南村群童欺我老无力.5 小时前
Flutter应用鸿蒙迁移实战:性能优化与渐进式迁移指南
javascript·flutter·ci/cd·华为·性能优化·typescript·harmonyos