你了解堆和栈的由来吗?

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

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

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

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

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

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

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

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

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

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

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

下面再来说说堆

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

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

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

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

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

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

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

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

Java中,(Heap)和(Stack)是内存管理的重要组成部分,它们各自存储不同类型的数据,并有不同的生命周期和管理策略: 1. **(Stack)**: - **位置**:位于程序运行的最顶层,通常被称为“当前”内存区域,是线程私有的。 - **数据结构**:基于LIFO(Last In First Out)原则,类似于书,新元素添加在顶部,删除也是从顶部开始。 - **内容**:存放局部变量、方法参数和返回地址等信息。每次方法调用,都会为其创建一个新的帧。 - **大小限制**:内存有限,超过限制可能导致溢出异常(StackOverflowError)。 - **生命周期**:当方法结束,帧及其包含的所有变量都将被清除。 2. **(Heap)**: - **位置**:在之下的内存区域,由JVM统一管理和分配。 - **数据结构**:基于动态分配,可以任意增加或减少,不是按照顺序排列的。 - **内容**:主要存放对象实例和数组,全局变量和静态变量也在上。 - **内存分配**:对象在上创建,垃圾回收负责回收不再使用的对象。 - **大小**:相对于来说,内存一般大得多,不会因为局部变量过多而受限。 - **生命周期**:直到对象被显式地设置为null或垃圾回收标记为不再引用,内存才被释放。 总结来说,用于存储程序的临时数据,对资源有严格的限制且易于管理;则用于长期保存对象实例,容量大但管理相对复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值