内存为什么要分堆栈在编程里,要是全部只用堆或者全部只用栈,可行吗?

内存分为堆和栈主要是为了满足不同的需求和解决不同的问题。

堆(Heap)主要用于动态分配内存,它的大小在程序运行时可以确定,允许动态添加和删除数据。堆的使用需要手动进行内存分配和释放,可通过函数如malloc()和free()来实现。由于堆的大小是可变的,因此堆上的内存可以在程序执行期间动态增长和收缩。

栈(Stack)主要用于存储函数的局部变量和参数等,它的分配和释放是由编译器自动管理的,一般遵循后进先出的原则。栈上的内存分配和释放是自动的,无需手动干预。由于栈的管理机制简单高效,因此对于函数调用和返回等操作,使用栈可以提高程序的运行效率。

如果全部只使用堆,可能会导致内存泄漏和碎片化的问题,因为需要手动分配和释放内存。而全部只使用栈,则会受限于栈的大小和生命周期的限制,无法实现动态分配和释放内存的需求。

因此,为了兼顾灵活性和效率,内存分为堆和栈,在编程中根据实际需求进行选择和使用。




其实我们都知道,计算机内存本来就是一块内存,没有堆栈之分。

在学编程的时候,我们应该都听过一句话 “如果程序结束之后仍然想要访问那一段数据就要用堆”,我想这个其实就是你疑问的关键了,堆和栈都有其自己的独特性,可能你了解这两个东西,但是我还是解释下,以免别的小伙伴在看答案的时候,不知道。

栈:就像我第一句话说的,本没有什么堆栈之分,但是编程语言的出现,就有了一个概念“函数”,这个函数之间是可以相互调用的(就像我们传递东西,比如:胡小然 将东西传递 胡小然2 将东西传递 胡小然3,之后需要从后面向前面反馈传递结果,这个传递的过程我们就可以理解为调用),那就出现了前后之分,这就是调用队列了,那这个队列有个什么特点呢,那就是先被调用进入队列的要最后出去,就是我们常说的先进后出(FILO),那么这时栈就出现了,而且它还有一个特点那就是线程独有(所以可以存放我们的临时变量),生命周期是随线程的。当然我所说的是内存栈的意思,其实“栈”就是个数据结构,是一种限定仅在表尾进行插入和删除操作的线性表,这个特性不正好是符合我刚才说的FILO嘛。所以你可以这么理解c++或者java(jvm)中的内存栈的概念,就是编程语言的作者为了管理内存使用了“栈”这种数据结构(说的再细点就是现代CPU体系结构决定了栈是管理函数调用和局部变量的最佳数据结构。因为CPU已经提供了现成的指令)。

堆:可算是一种特殊的数据结构,好像我们经常使用的二叉树。内存堆这个解释起来就更简单了,就是一块能自由分配的内存。它允许程序在运行时动态地申请某个大小的内存空间,比如:程序员向操作系统申请一块内存,当系统收到程序的申请时,会遍历一个记录空闲内存地址的链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。其特点就是分配的速度较慢,地址不连续,容易碎片化并且是由程序员申请,同时也必须由程序员负责销毁,否则导致内存泄露。像在java这种高级语言中,我们不比担心内存回收的问题,那是因为jvm已经在帮我们处理了。


上面说了这么多,就是想说明一下内存栈和内存堆出现的意义和作用,所以答案就出来了,那就是不能“只用堆或者全部只用栈”那样我们程序的调用和数据的存储都会出现问题。

好了,上面只是我自己一些理解,不对的地方还请大家指出,也希望对题主的疑问有帮助。




一个非常好的问题。堆栈是典型的两类内存分配方式,都是为了优化内存的使用,各有特点,用在不同的场景中。


一,栈

栈具有先进后出,后进先出特性,连续存储,操作简单,使用方便,无需管理,大部分芯片都对栈提供芯片级别的硬件支持,只需要移动指针就可以快速实现内存的分配和回收。比如局部变量使用栈内存,减少不必要的内存分配管理。


栈创建和删除的时间复杂度是O(1),速度快。但是不利于管理大内存,栈中的数据大小和生存周期都是确定的,缺乏灵活性。


二,堆

堆内存的管理机制相对复杂,有一套相应的分配策略,防止大量小碎片出现,同时加快查找。堆用于动态创建分配内存,创建和删除节点的时间复杂度是O(logn)。


堆的回收机制也复杂很多,根据内存大小不同,数据生命周期不同,采用相应的回收机制,涉及操作系统的堆管理。


因为堆内存的管理和申请相对复杂,更消耗系统资源,通常生命周期更长使用范围更广的全局变量使用堆内存。


我是工作多年的Web应用架构师,欢迎关注我,了解更多IT专业知识。




堆和栈是不能相互替代的。程序的结构是前部是栈,中部是程序体,后部是堆。前部和中部是链接的时候由编译器算好了的,执行过程中是固定不变的。而后部则可以随着程序的执行而改变长度。

那么为什么要把内存分成堆和栈呢?

栈是用来存储程序初期设定的变量的,这些变量在程序执行之前就要准备好。因此栈要放在程序的前部并且固定位置,否则程序就不知道该到那里去找这些变量。而程序的运行结果往往是不能预先确定的,所以把堆放在后部以便可以提供足够的内存保存运算结果。

至于栈用先进后出的方式,读写速度高,这是针对它的长度固定的特征设计出来的。而堆为了保持可扩张的特性,也设计了类似于二叉树的索引方式,以便可以高速地寻址,并可以方便地释放内存空间。




堆、栈在程序运行时有不同的特征和意义,两者都不能替代对方。

堆,是自由分配的内存,几乎在程序运行的任意时间都可以申请获得任意的大小(假设空闲内存充足),使用完之后在任意时间都可以释放。堆灵活的使用规则可以提高内存的使用效率,就是在需要时按需分配,不需要时释放以作他用。

栈,是遵守后进先出顺序的内存,只有运行到所在的作用域才会分配,在作用域内屏蔽掉之前同名的内存的访问,在退出作用域时释放掉以让之前同名的内存能被访问。栈的后进先出顺序有效地解决同名内存的问题,并有助于编程者掌控逻辑结构(例如函数调用等)。

如果把内存比作火箭的推进器,堆就是助推器,栈是主体的各级推进器。助推器可根据实际需要不安装、少安装或多安装,并且可随时分离。主体各级推进器,要先安装最高一级再安装下一级,最后安装一级推进器,使用的时候和安装是相反的顺序,只有下一级的推进器分离了才能使用上一级的。

正是各种内存不同的使用规则,才能适应现实中各种各样的需求,模拟出现实中的事物。因此不能只用栈或只用堆。

展开阅读全文

页面更新:2024-04-01

标签:堆栈   内存   推进器   结点   后部   数据结构   后进   队列   变量   生命周期   函数   分配   大小   程序   数据   财经

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top