堆和栈的区别

堆和栈的区别转:https://my.oschina.net/aofe/blog/267882堆和栈的区别:·1>堆空间的内存是动态分配的,一般存放对象,并且需要手动释放内存。需要程序员自

大家好,又见面了,我是你们的朋友全栈君。

转:https://my.oschina.net/aofe/blog/267882

堆和栈的区别:

·      1> 堆空间的内存是动态分配的,一般存放对象,并且需要手动释放内存。需要程序员自己申请并且指明大小,如C语言的malloc函数。

·      2> 栈空间的内存由系统自动分配,一般存放局部变量等,不需要手动管理内存。例如声明函数中的一个局部变量int b,系统在栈中自动为b开辟空间。

接下来我将从以下几个方面来阐述堆与栈的区别;

    管理方式:

        对于栈来讲,由编译器自动管理,无需我们手动控制。

        对于堆来说,释放工作由程序员控制,容易产生memory warning。

    申请大小:

        栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域.即栈顶的地址和栈的最大容量是系统预先规好的。栈的大小是1M,如果申请空间超过栈的剩余空间时,将提示overflow.因此,能从栈获得的空间较小。

        堆:堆是向高地址扩展的数据结构,是不连续的内存区域.这是因为系统是用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址.堆得大小受限于计算机系统中有效地虚拟内存.由此可见,堆获得的空间比较灵活,也比较大。

    碎片问题:

        对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。

        对于栈来讲,则不会存在这个问题,因为栈是先进后出得队列,它们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出。

    分配方式:

        堆都是动态分配的,没有静态分配的堆。

        栈有两种分配方式:静态分配和动态分配.静态分配是编译器完成的,比如局部变量的分配.动态分配由alloc函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需我们手工实现。

    分配效率:

        栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。

        堆则是C/C++函数库提供的,它的机制是很复杂的。例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。 

 

为什么栈比堆快?

从两方面来考虑:
      1.分配和释放,堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间(因为多次分配释放后会造成空洞),这些都会花费一定的时间,具体可以看看MALLOC和FREE的源代码,他们做了很多额外的工作,而栈却不需要这些。
      2.访问时间,访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。另外,堆的内容被操作系统交换到外存的概率比栈大,栈一般是不会被交换出去的。 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155155.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 第一章 语音信号处理概述

    第一章 语音信号处理概述一、语音交互语音交互(VUI:VoiceUserInterface)是指人与人或者人与设备通过自然语音进行信息传递的过程。语音交互的优势输入效率高:相对于键盘输入,语音输入的速度是传统输入方式的3倍以上(有权威统计分析得到的数据)。语音检索效率高;可跨空间,也称为远程语音交互,至少一米以上;指令可组合,比如:看一部周星驰的电影,评分8分以上。 解放双手和双眼,更安全:如车载系统的语音点播和语音导航场景(不可能一般用手开车,一边用手点播音乐);比如医疗场景,医生可以一边动手术,一边口语记录病.

    2022年5月9日
    42
  • Java环境变量PATH和CLASSPATH

    Java环境变量PATH和CLASSPATHJava开发中常用到环境变量的配置,下面简单介绍下Java中经常配置的环境变量:PATH和CLASSPATH。1、PATH环境变量1.1作用简介安装完JDK(JavaDevelopmentKit,Java开发套件)之后,可以在安装目录下找到两个子目录(bin目录和lib目录)。bin目录中包含着Java编译器等可执行文件。如果要运行执行java命令,必须得执行java命令对应的可执行文件的路径

    2022年6月21日
    29
  • SecureCRT的下载、安装( 过程非常详细!!值得查看)

    SecureCRT的下载、安装( 过程非常详细!!值得查看)SecureCRT的下载、安装和破解(过程非常详细!!值得查看)简单介绍下SecureCRT一、SecureCRT的下载二、SecureCRT的安装简单介绍下SecureCRTSecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件。SecureCRT支持SSH,同时支持Telnet和rlogin协议。Secu…

    2022年6月12日
    30
  • pycharm中创建虚拟环境「建议收藏」

    pycharm中创建虚拟环境「建议收藏」1什么是虚拟环境虚拟环境是用于依赖项管理和项目隔离的Python工具,允许Python站点包(第三方库)安装在本地特定项目的隔离目录中,而不是全局安装(即作为系统范围内的Python的一部分)。这听起来不错,但到底什么是虚拟环境呢?虚拟环境只是一个包含三个重要组件的目录:·安装了第三方库的site-packages/文件夹。·系统上安装的Python可执行文件的symlink符号链接。·确保执行Python代码的脚本使用在给定虚拟环境中安装的Python解释器和站点包。2.为什么使用虚

    2022年8月29日
    2
  • JavaScript 常用转义字符

    JavaScript 常用转义字符JavaScript 的转义字符依然是 下面是常用的转义字符 b 代表退格 t 代表一个制表符 即一个 Tab 空格 n 换行回车 v 垂直的制表符 r 回车 双引号 单引号 反斜线 即 OOO 使用八进制表示的拉丁字母 OOO 表示一个 3 位的八进制整数 范围是 000 377 xHH 使用十六进制数表示的拉丁字母 HH 表示一

    2025年8月25日
    3
  • java map 缓存_缓存用于

    java map 缓存_缓存用于缓存什么是缓存?平常的开发项目中,多多少少都会使用到缓存,因为一些数据我们没有必要每次查询的时候都去查询到数据库。缓存的使用场景:在Java应用中,对于访问频率高,更新少的数据,通常的方案是将这类数据加入缓存中,相对从数据库中读取,读缓存效率会有很大提升。在集群环境下,常用的分布式缓存有Redis等。但在某些业务场景上,可能不需要去搭建一套复杂的分布式缓存系统,在单机环境下,通常是会希望使用内部的缓存(LocalCache)。使用map缓存方案:基于ConcurrentHashMap实现数

    2022年9月27日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号