我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解JS内存空间

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解JS内存空间

概述

变量对象与堆内存


var a = 20;
var b = 'abc';
var c = true;
var d = { m: 20 }

在很长一段时间里认为内存空间的概念在JS的学习中并不是那么重要。可是后我当我回过头来重新整理JS基础时,发现由于对它们的模糊认知,导致了很多东西我都理解得并不明白。比如最基本的引用数据类型和引用传递到底是怎么回事儿?比如浅复制与深复制有什么不同?还有闭包,原型等等。

因此后来我才渐渐明白,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认知。

一、栈与堆

注:栈,也可以叫堆栈

与C/C++不同,JavaScript中并没有严格意义上区分栈内存与堆内存。因此我们可以粗浅的理解为JavaScript的所有数据都保存在堆内存中。但是在某些场景,我们仍然需要基于堆栈数据结构的思路进行处理,比如JavaScript的执行上下文(关于执行上下文我会在下一篇文章中总结)。执行上下文在逻辑上实现了堆栈。因此理解堆栈数据结构的原理与特点任然十分重要。

要简单理解栈的存取方式,我们可以通过类比乒乓球盒子来分析。如下图左侧。

乒乓球盒子与栈类比

这种乒乓球的存放方式与栈中存取数据的方式如出一辙。处于盒子中最顶层的乒乓球5,它一定是最后被放进去,但可以最先被使用。而我们想要使用底层的乒乓球1,就必须将上面的4个乒乓球取出来,让乒乓球1处于盒子顶层。这就是栈空间先进后出,后进先出的特点。图中已经详细的表明了栈空间的存储原理。

堆存取数据的方式,则与书架与书非常相似。

书虽然也整齐的存放在书架上,但是我们只要知道书的名字,我们就可以很方便的取出我们想要的书,而不用像从乒乓球盒子里取乒乓一样,非得将上面的所有乒乓球拿出来才能取到中间的某一个乒乓球。好比在JSON格式的数据中,我们存储的key-value是可以无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。

二、变量对象与基础数据类型

JavaScript的执行上下文生成之后,会创建一个叫做变量对象的特殊对象(具体会在下一篇文章与执行上下文一起总结),JavaScript的基础数据类型往往都会保存在变量对象中。

严格意义上来说,变量对象也是存放于堆内存中,但是由于变量对象的特殊职能,我们在理解时仍然需要将其于堆内存区分开来。

基础数据类型都是一些简单的数据段,JavaScript中有5中基础数据类型,分别是Undefined、Null、Boolean、Number、String。基础数据类型都是按值访问,因为我们可以直接操作保存在变量中的实际的值。

三、引用数据类型与堆内存

与其他语言不通,JS的引用数据类型,比如数组Array,它们值的大小是不固定的。引用数据类型的值是保存在堆内存中的对象。JavaScript不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值都是按引用访问的。这里的引用,我们可以粗浅地理解为保存在变量对象中的一个地址,该地址与堆内存的实际值相关联。

为了更好的搞懂变量对象与堆内存,我们可以结合以下例子与图解进行理解。


var a1 = 0;   // 变量对象
var a2 = 'this is string'; // 变量对象
var a3 = null; // 变量对象

var b = { m: 20 }; // 变量b存在于变量对象中,{m: 20} 作为对象存在于堆内存中
var c = [1, 2, 3]; // 变量c存在于变量对象中,[1, 2, 3] 作为对象存在于堆内存中

上例图解

因此当我们要访问堆内存中的引用数据类型时,实际上我们首先是从变量对象中获取了该对象的地址引用(或者地址指针),然后再从堆内存中取得我们需要的数据。

理解了JS的内存空间,我们就可以借助内存空间的特性来验证一下引用类型的一些特点了。

在前端面试中我们常常会遇到这样一个类似的题目


// demo01.js
var a = 20;
var b = a;
b = 30;

// 这时a的值是多少?
// demo02.js
var m = { a: 10, b: 20 }
var n = m;
n.a = 15;

// 这时m.a的值是多少

在变量对象中的数据发生复制行为时,系统会自动为新的变量分配一个新值。var b = a执行之后,a与b虽然值都等于20,但是他们其实已经是相互独立互不影响的值了。具体如图。所以我们修改了b的值以后,a的值并不会发生变化。

demo01图解

在demo02中,我们通过var n = m执行一次复制引用类型的操作。引用类型的复制同样也会为新的变量自动分配一个新的值保存在变量对象中,但不同的是,这个新的值,仅仅只是引用类型的一个地址指针。当地址指针相同时,尽管他们相互独立,但是在变量对象中访问到的具体对象实际上是同一个。如图所示。

因此当我改变n时,m也发生了变化。这就是引用类型的特性。

demo02图解

通过内存的角度来理解,是不是感觉要轻松很多。除此之外,我们还可以以此为基础,一步一步的理解JavaScript的执行上下文,作用域链,闭包,原型链等重要概念。其他的我会在以后的文章慢慢总结,敬请期待。

内存空间管理

因为JavaScript具有自动垃圾收集机制,所以我们在开发时好像不用关心内存的使用问题,内存的分配与回收都完全实现了自动管理。但是根据我自己的开发经验,了解内存机制有助于自己清晰的认识到自己写的代码在执行过程中发生过什么,从而写出性能更加优秀的代码。因此关心内存是一件非常重要的事情。

JavaScript的内存生命周期

1. 分配你所需要的内存

2. 使用分配到的内存(读、写)

3. 不需要时将其释放、归还

为了便于理解,我们使用一个简单的例子来解释这个周期。


var a = 20;  // 在内存中给数值变量分配空间
alert(a + 100);  // 使用内存
var a = null; // 使用完毕之后,释放内存空间

第一步和第二步我们都很好理解,JavaScript在定义变量时就完成了内存分配。第三步释放内存空间则是我们需要重点理解的一个点。

JavaScript有自动垃圾收集机制,那么这个自动垃圾收集机制的原理是什么呢?其实很简单,就是找出那些不再继续使用的值,然后释放其占用的内存。垃圾收集器会每隔固定的时间段就执行一次释放操作。

在JavaScript中,最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,因此a = null其实仅仅只是做了一个释放引用的操作,让 a 原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。而在适当的时候解除引用,是为页面获得更好性能的一个重要方式。

在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但是全局变量什么时候需要自动释放内存空间则很难判断,因此在我们的开发中,需要尽量避免使用全局变量,以确保性能问题。要详细了解垃圾收集机制,建议阅读《JavaScript高级编程》中的4.3节

以上就是详解JS内存空间的详细内容,更多关于JS内存空间的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解JS内存空间

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java空间内存溢出怎么解决

Java空间内存溢出的解决方法如下:1. 增加内存:可以通过增加JVM的堆内存大小来解决内存溢出问题,可以通过-Xmx和-Xms参数来设置堆内存的大小。但是增加内存并不是最好的解决方法,因为这只是暂时的解决方案,如果程序存在内存泄漏或者内存
2023-05-31

C语言内存分布与heap空间分别详细讲解

一个程序本质上都是由BSS段、data段、text段三个组成的。这种概念在当前的计算机程序设计中是非常重要的一个基本概念,并且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统执行时的内存大小分配,存储单元占用空间大小的问题
2022-11-13

如何购买空间内存

要购买空间内存,您需要先选择一个合适的主机服务提供商,然后根据您的需求选择一个适合的主机计划。在购买主机计划时,您需要注意以下几点:1. 内存大小:根据您的网站或应用程序的需求选择合适的内存大小。2. 存储空间:根据您的网站或应用程序的需求
2023-05-31

JavaScript内存空间是什么

这篇文章给大家介绍JavaScript内存空间是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。概述变量对象与堆内存var a = 20;var b = abc;var c = true;var d = { m: 2
2023-06-15

Redis缓存空间优化实践详解

目录导读场景设定常规做法改进1-去掉属性名改进2-使用更好的序列化工具改进3-优化数据类型改进4-考虑ZIP压缩最终落地场景延伸导读缓存Redis,是我们最常用的服务,其适用场景广泛,被大量应用到各业务场景中。也正因如此,缓存成为了重要的
2023-04-20

c#怎么释放内存空间

释放 c# 对象内存的方法包括:显式释放 (obj = null)使用 using 语句使用垃圾回收器(gc):调用 gc.collect()调用 gc.waitforpendingfinalizers()使用 weakreference
c#怎么释放内存空间
2024-05-11

php主机空间内存不足怎么解决

如果您的PHP主机空间内存不足,请尝试以下解决方法:1. 清理不必要的文件和数据库:删除不必要的文件和数据库可以释放一些空间。2. 压缩文件:压缩文件可以减少文件的大小,从而节省空间。3. 增加主机空间:如果您的主机空间不足,可以考虑购买更
2023-06-06

C++内存模型与名称空间概念讲解

这篇文章主要介绍了C++内存模型与名称空间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-01-02

云服务器空间多大内存

首先,空间大小是影响云服务器存储容量的最基本因素之一。您需要确定您的数据量、流量和访问速度等因素,以便为云服务器选择合适的存储容量。通常情况下,云服务器可以存储数百GB、数PB甚至数EB级别的数据。对于一些大型的文件和数据,您可能需要选择更高级别的存储设备,例如SSD硬盘、NAS网络存储等。其次,您需要考虑云服务器的性
2023-10-27

windows8存储空间设置步骤详细图解

“存储空间”的新功能将利用一个物理存储设施组成数据池。这个数据池将使用 SATA、USB 和 SAS 硬盘创建,并且能够使用额外的硬件扩展。 这些称作“空间”的虚拟硬盘能够把 4TB 存储空间
2022-06-04

Oracle表空间详解

目录1. 基本概念2. 范围分区3. Hash分区(散列分区)4. 复合分区1. 基本概念oracle表分区是将一个大型表分割成更小、更易于管理的部分的技术。分区后的表被称为分区表,其中每个分区都可以独立地进行维护、管理和查询。表分区可基
2023-04-19

JS前端的内存处理的方法全面详解

这篇文章主要为大家介绍了JS前端的内存处理的方法全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-15

阿里云服务器释放内存空间的详细步骤

阿里云服务器作为企业级云服务器,其内存空间的管理非常重要,因为它直接关系到服务器的性能和运行效率。但是,如果内存空间使用过多,不仅会影响服务器的运行速度,还可能导致服务器的宕机。因此,如何有效地释放阿里云服务器的内存空间,是每个企业都需要考虑的问题。本文将详细说明阿里云服务器释放内存空间的步骤和方法。一、了解阿里
阿里云服务器释放内存空间的详细步骤
2023-11-02

编程热搜

目录