堆与栈的区别详细总结

2023-10-27

常见的数据结构:
数组,栈,队列,链表,树,图,散列表(哈希表)

堆与栈的区别
堆:队列优先,先进先出(FIFO—firstinfirstout)。
栈,先进后出(FILO—First-In/Last-Out)。
一般情况下,如果有人把堆栈合起来说,那它的意思是栈,可不是堆。


堆(数据结构):堆可以被看成是一棵树,如:堆排序。

栈(数据结构):一种先进后出的数据结构。

堆栈 都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。

补充说明:栈内存和堆内存
程序的内存分配:
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另
一块区域。 - 程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。

栈内存:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。
堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

区别:

    1.栈内存存储的是局部变量而堆内存存储的是实体;

    2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

    3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

举例:
比如主函数里的语句 int [] arr=new int [3];在内存中是怎么被定义的:

过程:主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来体现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都是有一个索引,数组这个实体在堆内存中产生之后每一个空间都会进行默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但在堆里是可以用的,因为初始化过了,但是在栈里没有),不同的类型初始化的值不一样。所以堆和栈里就创建了变量和实体:


那么堆和栈是怎么联系起来的呢?

我们刚刚说过给堆分配了一个地址,把堆的地址赋给arr,arr就通过地址指向了数组。所以arr想操纵数组时,就通过地址,而不是直接把实体都赋给它。这种我们不再叫他基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。(可以理解为c或c++的指针,Java成长自c++和c++很像,优化了c++)

堆和栈的相同点:
都可以做内存,都是一种数据结构。

不同点:
(1)申请方式不同
栈是由系统自动分配,而堆是人为申请开辟的。
(  栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表)
(2)申请的大小的不同
栈的空间比较小,而堆获得的空间比较大
一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M。
(3)申请的效率不同
栈由系统自动的分配,速度快,而堆一般速度比较慢。
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
(4)存储内容不同
栈在函数调用时,函数调用语句的下一条语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节堆的大小,堆中具体的内容是人为安排的
(5)底层不同
栈是连续的空间,而堆是不连续的空间。
(6)碎片问题
碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。
(6)分配方式
堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

原文链接:https://blog.csdn.net/qq_32900237/article/details/105159580

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆与栈的区别详细总结 的相关文章

  • 无法在 Android 10 中创建目录

    我无法在 android 10 中创建目录 它可以在 android Oreo 之前的设备上运行 我尝试了两种创建文件夹的方法 Using File mkdir File f new File Environment getExternal
  • HashMap不写入数据库

    我尝试在我的数据库中写入 但只写入发件人和消息 我不明白为什么会发生这种情况 我认为问题出在我使用 sendMessage 的地方 我认为问题是我没有什么可以做的读 写其他用户的主键 我在数据库中写入消息的活动 public class M
  • Java Try Catch Final 没有 Catch 的情况下会阻塞

    我正在审查一些新代码 该程序只有一个 try 和一个 finally 块 既然排除了 catch 块 那么如果 try 块遇到异常或任何可抛出的内容 它如何工作 它直接进入finally块吗 如果 try 块中的任何代码可以引发已检查异常
  • 使用 GWT CellTableBuilder 构建树表

    Is it possible to build a tree table like this http www sencha com examples ExamplePlace basictreegrid with the new Cell
  • 禁用 Eclipse Java 调试器的热代码替换 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在 Eclipse 中禁用热代码替换 https stackoverflow com questions 2594408 how do i disable hot code replace in
  • 使用cameltestsupport进行Camel单元测试,模板始终为空

    我正在用 Camel 做一个简单的单元测试 我想做的就是从文件 在资源下 读取 JSON 内容 将其发送到 Java 类进行验证 这是我试图测试的路线 无论我做什么 模板 我用来发送正文 json 始终为空 这是我的代码 public cl
  • 对话框上的 EditText 不返回任何文本

    我太累了 找不到错误 我没有发现任何错误 但我没有从 editText 收到任何文本 请看下面的代码 活动密码 xml
  • 如何从秘密字符串中制作 HMAC_SHA256 密钥以在 jose4j 中与 JWT 一起使用?

    我想生成 JWT 并使用 HMAC SHA256 对其进行签名 对于该任务我必须使用jose4j https bitbucket org b c jose4j wiki Home 我尝试根据秘密生成密钥 SecretKeySpec key
  • 使用 RecyclerView 适配器在运行时更改布局屏幕

    我有两个布局文件 如下所示 如果列表中存在数据 则我显示此布局 当列表为空时 我会显示此布局 现在我想在运行时更改布局 当用户从列表中删除最后一项时 我想将布局更改为第二张图片中显示的 空购物车布局 In getItemCount Recy
  • Firestore - RecycleView - 图像持有者

    我不知道如何编写图像的支架 我已经设置了 2 个文本 但我不知道图像的支架应该是什么样子 你能帮我告诉我图像的文字应该是什么样子才能正确显示吗 holder artistImage setImageResource model getArt
  • 如果使用的 JVM 是 x86 或 x64,则以不同的方式解决 Maven 依赖关系?

    我设置了一个 Maven 存储库来托管一些 dll 但我需要我的 Maven 项目根据使用的 JVM 是 x86 还是 x64 下载不同的 dll 例如 在运行 x86 版本 JVM 的计算机上 我需要从存储库下载 ABC dll 作为依赖
  • 内存一致性 - Java 中的happens-before关系[重复]

    这个问题在这里已经有答案了 在阅读有关内存一致性错误的 Java 文档时 我发现与创建 发生 之前 关系的两个操作相关的点 当语句调用时Thread start 每个具有 与该语句发生之前的关系也有一个 与 new 执行的每个语句之间发生的
  • 在java中实现你自己的阻塞队列

    我知道这个问题之前已经被问过并回答过很多次了 但我只是无法根据互联网上找到的示例找出窍门 例如this http tutorials jenkov com java concurrency blocking queues html or t
  • Java:正则表达式排除空值

    在问题中here https stackoverflow com questions 51359056 java regexp for a separated group of digits 我得到了正则表达式来匹配 1 到 99 之间的一
  • 将表值参数与 SQL Server JDBC 结合使用

    任何人都可以提供一些有关如何将表值参数 TVP 与 SQL Server JDBC 一起使用的指导吗 我使用的是微软提供的6 0版本的SQL Server驱动程序 我已经查看了官方文档 https msdn microsoft com en
  • 如何在 Eclipse Java 动态 Web 项目中使用 .properties 文件?

    我正在 Eclipse 中开发动态 Web 项目 我创建了一个 properties 文件来存储数据库详细信息 用户名 密码等 我通过右键单击项目和 New gt File 添加它 我使用了Java util包Properties类 但它不
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • Java:多线程内的 XA 事务传播

    我如何使用事务管理器 例如Bitronix http docs codehaus org display BTM Home JBoss TS http www jboss org jbosstm or Atomikos http www a
  • 嵌入式 Jetty - 以编程方式添加基于表单的身份验证

    有没有一种方法可以按如下方式以编程方式添加基于表单的身份验证 我用的是我自己的LdapLoginModule 最初我使用基本身份验证并且工作正常 但现在我想在登录页面上进行更多控制 例如显示徽标等 有没有好的样品 我正在使用嵌入式 jett

随机推荐

  • 求助:stm32+proteus+adc采集电压仿真显示为零

    求助一下大佬 因为板子上的oled不是ssd1306驱动的所以现在只能学习跑仿真 在学adc采集电压的实验 OLED显示没问题 现在的问题是采集不到电压 显示总是0 麻烦好心人帮我看看是哪里出了问题 软件用的keil mdk5 24 pro
  • Game【HDU-6873】【Splay】

    2020 Multi University Training Contest 9 G题 题意 有N个有各自高度的位置 按1 N从左到右排列 现在我们有两种操作 x y将第x列 第y行的方块 包括它上面的方块从右往左的移动过去 同时推动前面的
  • 【导入导出测试用例编写】

    导入导出测试用例编写 一 导出模板测试用例 二 导出数据测试用例 三 导入数据测试用例 一 导出模板测试用例 1 检查模板是否可以正常下载正常打开 2 检查模板表头格式展示是否正确 与系统列表中的字段是否一致 3 检查必填项 字段长度 字段
  • 接口性能 指标

    接口测试响应时间 通用得接口响应使时间分布情况 100ms为优良 500ms为及格 1000ms以上为不可忍受 金融接口响应时间得分布情况 100ms为优良 200ms为及格 300ms以上为不可忍受
  • 动态链接库(一)--动态链接库简介

    写在前面 自从微软推出的第一个版本的Windows操作系统以来 动态链接库 DLL 一直就是Windows操作系统的基础 动态链接库通常不能直接运行 也不能接收消息 它们一直是独立的文件 其中包含能被可执行程序或其他DLL文件调用来完成某项
  • 【解决ElementUI 和Antd的对话弹窗样式冲突问题】

    项目中使用了Antd 和element UI两种UI库 Antd是全局样式 element ui则是按需引入 在使用element ui的页面处点击退出 弹出的对话框就会样式失效 首先在随便一个地方点击退出登录看一下正常效果 再打开F12查
  • Unity3D中的ref、out、Params三种参数的使用

    目录 ref out Params ref 作用 将一个变量传入一个函数中进行 处理 处理 完成后 再将 处理 后的值带出函数 语法 使用时形参和实参都要添加ref关键字 using System Collections using Sys
  • JavaSE学习总结:面向对象编程

    Java面向对象编程 1 类与对象 1 1面向对象的理解 1 1 1面向对象和面向过程的区别 1 1 2面向对象的好处 1 1 3面向对象的思考步骤 1 2类与对象 1 2 1什么是类 1 2 2什么是对象 1 2 3二者的区别 1 2 4
  • ubuntu设置环境变量

    vim bashrc export VCPKG FORCE SYSTEM BINARIES 1 export VCPKG HOME PATH vcpkg export X VCPKG ASSET SOURCES x azurl http 1
  • GPT-4最强竞争对手Claude 2震撼发布,据说超过GPT-4?

    OpenAI 发布了 GPT 4 的 API 和令人兴奋的 最强插件 代码解释器 这无疑给竞争对手们敲响了警钟 而最近 Anthropic 旗下的 Claude 揭开了它的第二代面纱 免费使用Claude 2请加微信wyxyellow 相较
  • GAN之生成对抗网络(Matlab)

    代码来源 代码全文 clear all close all clc Basic Generative Adversarial Network Load Data load mnistAll mat trainX preprocess mni
  • DMRS在5G NR各种物理信道上的配置

    笔者在微信公众号GiveMe5G定期发布学习文章 更多更及时 欢迎订阅和分享 文章下方有二维码 本篇文章旨在介绍DMRS DeModulation Reference Signal 在5G中 DMRS广泛存在于各个重要的物理信道当中 如下行
  • MMdetection的Proposal原理和代码解析

    一 算法原理 接受N级score bbox pred anchor和image shape作为输入 通过anchor和框的偏移 bbox pred 得到proposal 然后对这些proposal做NMS 最后选出前num个 二 执行步骤
  • golang 组成树形格式

    该封装受到前端 js filter函数的启发看着特别简洁 一 封装一个函数 比较简单就是循环根据传入的 回调函数 进行过滤组成新的数组返回 func Filter T any arr T f func item T bool list T
  • 震动传感器介绍及实战(中断)

    项目要求 利用震动传感器实现点灯效果 当传感器察觉震动 led灯亮 否则不亮 接线及引脚 传感器信号引脚DO接PA4 led1灯的引脚接PB8 所以中断的信号源就是PA4引脚 配置STM32 PB8设置成output 输出给led 打开使能
  • 红黑树结构算法原理与代码解析

    红黑树 Red Black Tree 平衡二叉B树 是一种自平衡二叉查找树 是在计算机科学中用到的一种数据结构 典型的用途是实现关联数组 典型的普通顺序数组结构的增 删 查效率都是O n 但是红黑树进行读写操作时的效率可以稳定在O log
  • JAVA笔记

    目录 模板模式的理解 使用模板模式的例子 整合工厂模式 模板模式的理解 模板模式简单理解就是创建一个抽象父类作为模板 可以分两部分 一部分是定义了所有子类都需要执行的公共方法 这样就不用在每个子类中重复写相同代码 另一部分就是强制规定每个子
  • php面试题之四——PHP面向对象(基础部分)

    1 写出 php 的 public protected private 三种访问控制模式的区别 新浪网技术部 public 公有 任何地方都可以访问 protected 继承 只能在本类或子类中访问 在其它地方不允许访问 private 私
  • (Oracle技能篇) oracle数据库分页查询和各大数据库的分页查询

    1 oracle数据库分页 select from select a rownum rc from 表名 where rownum lt endrow a where a rc gt startrow 2 DB2数据库分页 Select f
  • 堆与栈的区别详细总结

    常见的数据结构 数组 栈 队列 链表 树 图 散列表 哈希表 堆与栈的区别 堆 队列优先 先进先出 FIFO firstinfirstout 栈 先进后出 FILO First In Last Out 一般情况下 如果有人把堆栈合起来说 那