2018-07-31 计算机内存与堆栈

感觉上一周给自己挖了一个深坑,在繁重的工作任务之下,感觉自己完全没有办法重现当时联系过的js的栈与队列,再深刻剖析一下数据结构中的栈与队列的形式与变化。

不管怎样,先解决一个小坑,今天看了看计算机的堆栈,当然堆栈还是与内存有关的,那究竟计算机中的堆栈是什么呢?

首先,说堆栈肯定要从内存开始讨论。计算机五个部分,输入设备,输出设备,运算器,存储器,控制器,内存自然是属于存储器的。存储器包括很多,包括硬盘,包括内存,包括虚存。当然广义上来说,u盘等存储也是存储器,不过这都是我们平常了解的概念,计算机的存储器其体系大概是这样的:


如图所示,上文所说的硬盘,内存,实际上都包含在主存之中,而所说的U盘其实就属于辅存部分。此外我刚才还说到了虚存,上图之中也体现了缓存,这其实又可以画出一个层次图。



实际上对于电脑的物理设备就是,CPU,内存,硬盘(二级存储),而缓存,虚存是为了计算机更好的处理数据而虚拟出来的区块。缓存是在内存之上的一块空间,不过相比其他的内存区域,他的存取速度要快很多;虚拟内存是处于二级存储上的一块空间,它是用来存储内存上不常用的一些符号和数据等内容,相比于普通二级存储它自然也速度也会快一些。其逻辑自然如上图,CPU需要数据的时候会先从缓存中寻找,如果寻找不到,再到内存中寻找,如果还是没有,会再到虚拟内存中寻找,最后找不到会从二级存储中寻找。

那么为什么这两张图都CPU呢?尤其我们知道,CPU,中央处理器嘛,按上面所说的分类,怎么着也应该是运算器和控制器,怎么也轮不到存储器吧?但实际上CPU中也有一个存储的空间,叫做寄存器。我们都知道,冯诺依曼计算机思想的中心原则就是指令和数据一起存储,那么作为一条指令,在CPU上运行,它的存储在哪里?为了提升这种在运算中的数据和指令的存取速度,所以有了寄存器,这些正在运算中的指令与数据就存在了寄存器之上。

既然我们今天想要讨论内存,那就聚焦于内存之上,这其中会涉及到很多有关内存的分段,分页,缺页中断算法等理论,这些与我们要讨论的堆栈无关,但是其实还是可以讲一下(或者挖个坑)。

说完了这些我们可以再稍微明确一下堆栈是什么,简单来说,堆栈只是两个数据结构,这一点其实再上一篇中已经简单提到了,那么为什么我们再计算机运算,存储的过程中反复提到了堆栈的概念呢?因为,堆栈是在进行内存管理中的重要概念,内存的存储方式实际上就是一块一块的地址,而堆与栈就是通过程序员主动或者程序自动的方式,为数据分配相应的地址空间。

在写程序的时候,我们知道栈与堆最重要的区别就是:栈是由编译器自动分配的,其中存储的是函数的参数值,局部变量的值等;堆是由程序员自己主动分配的,每当新建一个变量,会在堆中新开辟一块地址区域。这样说其实比较笼统,也不够准确,因为,本身当我们去new一个变量的时候,它也会有赋值操作,也会有调用函数,那它不是既存在于堆中,又存在于栈中了么?

所以,其实那样对于堆栈的解释不够准确,其实这样的解释并不矛盾的。因为栈之中,存在的是新建的变量的一个地址的引用,而堆中存在的是这个引用变量的真实地址,其内部是该变量的真实内容。所以当数据改变的时候,实际上是改变了这个地址的引用,所以存在堆中的引用变量也会改变,这也就涉及到了深浅复制的问题。(见https://www.jianshu.com/p/65bf223bbba9)


那么这样严格来说,好像计算机内存于堆栈是完全没有什么关系的东西,但是或许是他们的结构类似吧,也有相似的映射关联,内存有与具体文件的映射关系,而栈是和堆之间有映射关系,而且我们常常对于内存会有列状的地址栏表示,与栈的结构会有所相似,但是实际上在内存分配的大部分时候是不连续且随机的,并不具有栈那么规则的结构,其中会有内存的碎片,这与栈和堆也是完全不类似且没什么联系的。

唯一我们需要知道的就是,栈和堆中的内容都是有地址的,栈内存中变量都是有地址的,无论是直接字面量,还是变量,还是地址的引用,都是有独立的地址的,尤其是地址的引用这里需要注意,这个变量有自己单独的地址,与在堆中的引用变量是完全不同且没有任何直接关系的地址,堆中的引用变量自然也有自己独立的地址,这些数据都存在内存之上,一部分在缓存之中,当CPU处理的时候会将他们放到寄存器之上。在基础之上,大概就是这样了,如果需要再了解一些栈帧,地址方向等知识,我感觉自己还需要再准备一下,仔细了解一下内存的构造。

你可能感兴趣的:(2018-07-31 计算机内存与堆栈)