栈内存和堆内存在了解一门语言底层数据结构上,挺重要的,做了个总结

JS中的栈内存堆内存

JS的内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)。

其中栈存放变量,堆存放复杂对象,池存放常量,所以也叫常量池。


栈数据结构

栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。栈被称为是一种后入先出(LIFO,last-in-first-out)的数据结构。由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问。为了得到栈底的元素,必须先拿掉上面的元素。


堆数据结构

堆是一种经过排序的树形数据结构,每个结点都有一个值。

通常我们所说的堆的数据结构,是指二叉堆。

堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。

由于堆的这个特性,常用来实现优先队列,堆的存取是随意,这就如同我们在图书馆的书架上取书,

虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的书,

我们只需要关心书的名字。


基本数据类型
  1. Sting
  2. Number
  3. Boolean
  4. null
  5. undefined
  6. Symbol

基本数据类型保存在栈内存中,因为基本数据类型占用空间小、大小固定,通过按值来访问,属于被频繁使用的数据。

let num1 = 1;
let num2 = 1;
// 闭包中的基本数据类型变量不保存在栈内存中,而是保存在堆内存中

引用数据类型

Array,Function,Object...可以认为除了上文提到的基本数据类型以外,所有类型都是引用数据类型。

引用数据类型存储在堆内存中,因为引用数据类型占据空间大、大小不固定。

如果存储在栈中,将会影响程序运行的性能;

引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。

当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体

// 基本数据类型-栈内存
let a1 = 0;
// 基本数据类型-栈内存
let a2 = 'this is string';
// 基本数据类型-栈内存
let a3 = null; // 对象的指针存放在栈内存中,指针指向的对象存放在堆内存中
let b = { m: 20 };
// 数组的指针存放在栈内存中,指针指向的数组存放在堆内存中
let c = [1, 2, 3];


基本数据类型的复制
let a = 20;
let b = a;
b = 30;
console.log(a); // 20

a、b 都是基本类型,它们的值是存储在栈内存中的,a、b 分别有各自独立的栈空间, 所以修改了 b 的值以后,a 的值并不会发生变化。


引用数据类型的复制
let m = { a: 10, b: 20 };
let n = m;
n.a = 15;
console.log(m.a) // 15

m、n都是引用类型,栈内存中存放地址指向堆内存中的对象, 引用类型的复制会为新的变量自动分配一个新的值保存在变量中, 但只是引用类型的一个地址指针而已,实际指向的是同一个对象, 所以修改 n.a 的值后,相应的 m.a 也就发生了改变。


栈内存和堆内存的优缺点

在JS中,基本数据类型变量大小固定,并且操作简单容易,所以把它们放入栈中存储。

引用类型变量大小不固定,所以把它们分配给堆中,让他们申请空间的时候自己确定大小,这样把它们分开存储能够使得程序运行起来占用的内存最小。

栈内存由于它的特点,所以它的系统效率较高。

堆内存需要分配空间和地址,还要把地址存到栈中,所以效率低于栈。


栈内存和堆内存的垃圾回收

栈内存中变量一般在它的当前执行环境结束就会被销毁被垃圾回收制回收, 而堆内存中的变量则不会,因为不确定其他的地方是不是还有一些对它的引用。 堆内存中的变量只有在所有对它的引用都结束的时候才会被回收。


闭包与堆内存

闭包中的变量并不保存中栈内存中,而是保存在堆内存中。 这也就解释了函数调用之后之后为什么闭包还能引用到函数内的变量。

function A() {
let a = 1;
function B() {
console.log(a);
}
return B;
}
let res = A();

转自

js的栈内存和堆内存的更多相关文章

  1. JS栈内存与堆内存

    ㈠JavaScript变量 ⒈分类 ⑴JavaScript中的变量分为基本类型和引用类型. ⑵基本类型就是保存在栈内存中的简单数据段. ⑶引用类型指的是那些保存在堆内存中的对象. ⒉基本类型  基本类 ...

  2. JavaScript变量——栈内存or堆内存

    原文  http://blog.csdn.net/xdd19910505/article/details/41900693 堆和栈这两个字我们已经接触多很多次,那么具体是什么存在栈中什么存在堆中呢?就 ...

  3. 牛客网Java刷题知识点之内存的划分(寄存器、本地方法区、方法区、栈内存和堆内存)

    不多说,直接上干货!  其中        1)程序计数器:用于指示当前线程所执行的字节码执行到了第几行,可以理解为当前线程的行号指示器.每个计数器志勇赖记录一个线程的行号,所以它是线程私有的.    ...

  4. JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝

    前言 想写好前端,先练好内功. 栈内存与堆内存 .浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScri ...

  5. JVM存储位置分配——java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配

    Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”. 根据“Java ...

  6. Java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配

    转自:https://blog.csdn.net/leunging/article/details/80599282 感谢CSDN博主「leunging」的总结分享 ———————————————— ...

  7. (转)java内存分配分析/栈内存、堆内存

    转自(http://blog.csdn.net/qh_java/article/details/9084091) java内存分配分析/栈内存.堆内存 java内存分配分析 本文将由浅入深详细介绍Ja ...

  8. java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  9. 目录_Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)

    1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘 ...

随机推荐

  1. Numerical Sequence(hard version),两次二分

    题目: 题意: 已知一个序列: 112123123412345123456123456712345678123456789123456789101234567891011... 求这个序列第k个数是多 ...

  2. Redis做为缓存的几个问题

    缓存理流程: 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果. 1.缓存雪崩 解决方案3:如果缓存数据库是分布 ...

  3. 数据可视化实例(三): 散点图(pandas,matplotlib,numpy)

    关联 (Correlation) 关联图表用于可视化2个或更多变量之间的关系. 也就是说,一个变量如何相对于另一个变化. 散点图(Scatter plot) 散点图是用于研究两个变量之间关系的经典的和 ...

  4. 【Nginx】如何配置Nginx日志?这是最全面的一篇了!!

    写在前面 日志对于统计排错来说非常有利的.本文总结了 Nginx 日志相关的配置如 access_log. log_format.open_log_file_cache. log_not_found. ...

  5. [CISCN2019 华东南赛区]Double Secret

    0x01 进入页面如下 提示我们寻找secret,再加上题目的提示,猜测这里有secret页面,我们尝试访问,结果如下 根据它这个话的意思,是让我们传参,然后它会给你加密,我们试一下 发现输入的1变成 ...

  6. Captura - 免费好用还开源的录屏软件

    首先下载这个软件,国内下载很慢这里提供一个国内下载UCloud-OSS 软件打开后默认英文,现在我们切换到中午模式 在录制屏幕的同时获取声音

  7. CSS把容器中的内容限制行数,在超过行数后,在最后一行显示"..."

    <style type="text/css"> .main{ width: 400px; background-color: #3498db; display: -we ...

  8. Java中lambda(λ)表达式的语法

    举一个排序的例子,我们传入代码来检查一个字符串是否比另一个字符串短.这里要计算: first.length() - second.length() first和second是什么?他们都是字符串.Ja ...

  9. Spring Boot+MyBatis+MySQL读写分离

    读写分离要做的事情就是对于一条sql语句该选择去哪个数据库执行,至于谁来做选择数据库的事情,无非两个,1:中间件(比如MyCat):二:程序自己去做分离操作. 但是从程序成眠去做读写分离最大的弱点就是 ...

  10. 使用 flask 构建我的 wooyun 漏洞知识库

    前言 最近在学 flask,一段时间没看,又忘得差不多了,于是弄这个来巩固一下基础知识 漏洞总共包括了 88820 个, Drops 文章总共有 1235 篇,全来自公开数据,在 Github 上收集 ...