你了解堆和栈的由来吗?

人们提出内存中堆和栈这两个概念,肯定是要解决当时所遇到的问题,不会为了提出概念而提概念。堆和栈都是为了解决一些问题而发展出来的结果,并没有任何的高深之处。

要搞懂堆和栈的概念是如何来的,就需要从计算机诞生时说起了。

在冯诺依曼提出冯诺依曼计算机时,那是只有存储器,没有将存储器进一步划分。在编程时,整个内存空间任你使用,随便写,整个地址空间,每一个比特都是全局变量。

但时间久后,人们发现,这样写出来的代码真的很难维护、难以让人理解,写出来的代码都是面条代码。

后来,为了解决面条代码的问题,ALGOL提出了结构化编程。每个模块都使用begin和end进行包裹,包裹的部分使用局部变量,不能引用全局变量。

你了解堆和栈的由来吗?_第1张图片

这时,科学家们又遇到了新的问题,在包裹的部分,如何才能实现局部变量呢?

当进入到每个模块时,为这个块单独开辟一块内存空间,。块空间是可以进行嵌套,比如A函数调用B函数,B函数调用C函数。这种嵌套有个特点,最后执行的块,一定是最先执行完成,最先释放空间,然后依次执行和释放。你会发现这就是我们现在所使用的栈,后进先出,即Last-In-First-Out数据结构。

这就是栈的由来,也是结构化编程的结果。

栈最早是体现在计算伯努利数的程序中,由程序员师姐ada编写,大致思路就是从仓库中获得数据,然后计算,然后将结果返回仓库。

你了解堆和栈的由来吗?_第2张图片

结构化编程在上世纪60~70年代很流行,也逐渐被大众所接受,但是又带来了新的问题,这种大量的Push和Pop操作,很容易影响程序执行效率。

为了提高程序执行效率,DEC率先在CPU中增加了四条指令,分别是Push、Pop、PushJ、PopJ;后来出现的CPU,几乎都是遵照了这种范式,一直延续到今天。

下面再来说说堆

我们知道,最早的高级语言是Fortran,这门语言现在还在TIOBE排行榜前十的位置,还是很受欢迎的。早期的Fortran,必须在内存中定义好维度和长度,用今天的话来讲,就是在编译时使用静态变量将空间分配好,不支持在运行时进行动态分配。

你了解堆和栈的由来吗?_第3张图片

如果你今天使用这种语言进行开发,不知道你会换多少个键盘和鼠标。我想你一定会疯掉的,这是什么垃圾玩意。当时的开发人员当然也不爽,严重影响到开发效率。

为了解决这一问题,在上世纪60年代初,BCPL语言首次引入了堆的概念,提供GETBLK和FREEBLK两个函数,用于动态申请内存空间,终于不用在代码里将数据定死了。

在到后来的C语言,就是我们都使用过的malloc和free函数。

这就是堆,为了能让你在运行时才决定内存大小的分配,而不必在编译时就将大小定死。堆并不能准确指代什么,而是一种泛指,泛指操作系统给你一块内存空间存放你任意的东西,不要与数据结构中的堆混合了。

堆和栈是不同的,大多数语言栈上的数据大小在编译期就必须要确定的。当你在类或函数中定义变量时,就是在使用栈;当你使用malloc或new时,就是在使用堆。

我上面说的堆和栈只是一些概念,仅供了解,当你具体在使用堆和栈时,肯定还会有很多细节之处。比如。栈的长度能无限大吗?栈的大小由什么决定?在堆里频繁申请和释放内存,如何减少内存窟窿?如何提高效率?每次malloc后,又要free,这一过程不仅繁琐而且又不安全,有没有在程序运行时自动对内存进行申请和释放(也就是现在的GC)。

如果你对这些基本概念进行理解后,在去理解这些细节就很简单了,没有你想象中的那么难。

你可能感兴趣的:(笔记,java,开发语言)