参考:阮一峰-汇编语言入门教程
参考:https://blog.csdn.net/u013448372/article/details/108087346
本文主要内容:
- 了解汇编语言的堆栈内存模型的设计
- 堆栈模型与Javascript
一、一些堆栈的设计知识
了解的内容,几乎都出自 阮一峰 的教程(链接文章开头有)!
这里有一个关于(出自这里):寄存器(CUP存储),内存(内存条),和辅存(硬盘)的比喻 ~
寄存器
就是你的口袋。身上只有那么几个,只装最常用或者马上要用的东西。
内存
就是你的背包。有时候拿点什么放到口袋里,有时候从口袋里拿出点东西放在背包里。
辅存
就是你家里的抽屉。可以放很多东西,但存取不方便。
堆的了解
这种因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始地址开始,从低位(地址)向高位(地址)增长。Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。
栈的理解
除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域。
Stack 是由内存区域的结束地址开始,从高位(地址)向低位(地址)分配。
RAM
随机存取存储器(英语:Random Access Memory,缩写:RAM),也叫主存,是与CPU直接交换数据的内部存储器。
ROM
ROM为只读存储器(Read-Only Memory)的简称,一种只能读出事先所存数据的固态半导体存储器。
我们常用的内存条就是 RAM
这里做了一个图,展示了各级存储之间的关系。存储速度的比较。
二、JS 与堆栈模型
其实在我们写代码的时候,我们基本都不需要去理解堆栈模型的底层设计。只要专注于自己使用的语言,和业务逻辑即可。
俗话说:工欲善其事,必先利其器
。 适当的了解一下,也不是什么坏事情!
我们都知道 JS 有 6种 基本数据类型,和 1种 复杂数据类型构成,不支持任何自定义类型的机制。
6种基本数据类型:
- Undefined
- Null
- Boolean
- Number
- String
- Symbol (ES6新增)
一种复杂数据类型:
-
Object
这种复杂类型包括:
Function
,Array
,RegExp
,Object
…它们的
typeof
操作是object
PS:理论上函数本质就是对象。但是为了其他的原因,typeof 的操作的会有些不同,它的返回值是
function
对于JS来说,存储它们的方式是不一样的。这就是 基本类型
和 引用类型
的区别!
* 基本类型的存储
基本类型我们都知道赋值变量,传递的时候,传递的是值。为什么?
仔细回想一下上面说过的的,关于堆栈的知识!
因为 基本类型 是存放在 栈 里面的。更准确的说,是存放在 执行环境
里面的!
而 执行环境
是函数 执行环境栈
的 一帧
。
PS:关于这点,你可以理解为JS 就是运行在一个函数的栈里面的,最外层的是Window 全局的执行环境,这个环境比较特殊,
只有在关闭网页的时候才会被回收内存。关于函数的执行环境可以去看浏览器的:执行环境相关文章。
当函数结束的时候,执行环境就会被弹出,栈里面的内容都会被释放掉,内存会被回收!
内存回收以后,基本类型的数据就会被释放!
* 复杂类型的存储
但是我们的 复杂数据类型,也就是 引用类型 情况是不一样的,引用类型存放在 堆 里面。
我们拿到的 指向这个堆的地址的指针,但是我们可以通过这个指针操作到这个 堆里面的数据。
这个也就是为什么我们把引用类型不管赋值了多少次,操作的还是同一个对象,无意间修改了引用类型的值的原因。
当执行环境被弹出以后,引用类型变量的值,暂用的空间并不会马上就被释放回收,而是需要依赖 垃圾回收机制 的清理。
在JS中垃圾回收有两种:
- 标记清除
- 引用清除
用的多的是 标记清除 清除。
当执行环境销毁的时候,引用类型这个时候就是会垃圾回收机制标记为:出栈
然后等带下一轮的垃圾回收机制运行,执行释放内存操作。整个变量的生命周期就算是结束了!
总结
关于浏览器数据存储的知识点,只是小小的一个点。但是这次在我这里产生了质的变化。因为在学习了:浏览器工作原理
, 事件循环
, 执行环境
… 知识点以后,结合起来,形成了以系统的知识。这一点点对我来说形成了一个闭环!