你需要知道的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,此时修改c1为200后,实际上操作的就是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节点、闭包等等。

相关推荐
曹牧1 小时前
C#:空合并运算符
java·前端·数据库
小羊没烦恼!2 小时前
铁道部新客票系统设计(二)
开发语言·前端·数据库·python·oracle·c#·php
智能直播5 小时前
RK3518:1.5G 内存 + 8G 存储,如何跑起硬件编解码、Web、AI 识别、绿幕特效
前端·人工智能·5g
掘金酱6 小时前
【10.24 特别活动】AI 时代,程序员的新饭碗在哪里?
前端·人工智能·后端
excel6 小时前
多进程环境下使用 PM2 部署 Socket.IO:需要注意什么
前端
IT_陈寒6 小时前
Redis的原子性竟然失效了?记一次分布式锁翻车实录
前端·人工智能·后端
Interview Aid1127 小时前
Snowflake OA 面试真题:前缀和、BFS 与动态规划
面试·动态规划·宽度优先
_菜鸟果果8 小时前
高德地图 JS API 2.0 在国产 Linux/ARM 电脑上渲染失败 的排查与解决
linux·开发语言·javascript
时间的情敌8 小时前
《回顾 2018 前端:Vue2 成熟期,Webpack4 发布,PWA 大火》
前端