当前位置: 首页 > 编程日记 > 正文

栈和堆的区别(转 知乎)

管理方式:栈由编译器自动管理;堆由程序员控制,使用方便,但易产生内存泄露。

生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。

空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认2M或10M);堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G空间。

存储内容:栈在函数调用时,首先压入主调函数中下条指令(函数调用语句的下条可执行语句)的地址,然后是函数实参,然后是被调函数的局部变量。本次调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的指令地址,程序由该点继续运行下条可执行语句。堆通常在头部用一个字节存放其大小,堆用于存储生存期与函数调用无关的数据,具体内容由程序员安排。

分配方式:栈可静态分配或动态分配。静态分配由编译器完成,如局部变量的分配。动态分配由alloca函数在栈上申请空间,用完后自动释放。堆只能动态分配且手工释放。

分配效率:栈由计算机底层提供支持:分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。Windows系统中VirtualAlloc可直接在进程地址空间中分配一块内存,快速且灵活。

分配后系统响应:只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则报告异常提示栈溢出。

操作系统为堆维护一个记录空闲内存地址的链表。当系统收到程序的内存分配申请时,会遍历该链表寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序。若无足够大小的空间(可能由于内存碎片太多),有可能调用系统功能去增加程序数据段的内存空间,以便有机会分到足够大小的内存,然后进行返回。,大多数系统会在该内存空间首地址处记录本次分配的内存大小,供后续的释放函数(如free/delete)正确释放本内存空间。

此外,由于找到的堆结点大小不一定正好等于申请的大小,系统会自动将多余的部分重新放入空闲链表中。

碎片问题:栈不会存在碎片问题,因为栈是先进后出的队列,内存块弹出栈之前,在其上面的后进的栈内容已弹出。而频繁申请释放操作会造成堆内存空间的不连续,从而造成大量碎片,使程序效率降低。

可见,堆容易造成内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和内核态切换,内存申请的代价更为昂贵。所以栈在程序中应用最广泛,函数调用也利用栈来完成,调用过程中的参数、返回地址、栈基指针和局部变量等都采用栈的方式存放。所以,建议尽量使用栈,仅在分配大量或大块内存空间时使用堆。

使用栈和堆时应避免越界发生,否则可能程序崩溃或破坏程序堆、栈结构,产生意想不到的后果。

转载于:https://www.cnblogs.com/wsw-seu/p/8276119.html

相关文章:

到这个年纪为什么我还要开始学习理解参与区块链?

【顺势而为,与时俱进的需要】看来我对信息的敏感程度还不够,最近才认真研读了相关文件:国务院关于印发“十三五”国家信息化规划的通知国发〔2016〕73号1信息技术创新代际周期大幅缩短,创新活力、集聚效应和应用潜能裂变式释放&am…

JavaScript小记

项目进行中需求变化&#xff0c;把所有的图片的呈现出渐出效果&#xff0c;我首先想到了filters&#xff1a;滤镜&#xff0c; <html><head> </head> <script language"JavaScript">function picload(){img.filters.revealTrans.apply()im…

Ant Design of Vue —— setFieldsValue方法 动态操作Switch组件

在开发中经常使用Form组件管理表单&#xff0c;这次想通过form提供的setFieldsValue()方法动态改变Switch组件状态&#xff0c;却没有生效。 加入valuePropName属性之后&#xff0c;就可以使用动态操作Switch组件了。 <a-switch v-decorator"[haveChildren, { valuePro…

打印机的大小设置

procedure SetPrinterPaper(APaperNo: Integer; APaperWidth, APaperHeight: Double); //设置当前打印机的纸张大小 //纸张号 &#xff19; A4 13 B5 //页宽和页高&#xff0c;单位mm var Device: array[0..255] of char; Driver: array[0..255] of char; Port: array[0..255]…

C# 对ListT取交集、连集及差集

實際演練 ※本文使用int為例&#xff0c;若為使用自訂之DataModel&#xff0c;需實作IEquatable<T>介面才能使用 1. 取交集 (A和B都有) List A : { 1 , 2 , 3 , 5 , 9 } List B : { 4 , 3 , 9 } var intersectedList list1.Intersect(list2);結果 : { 3 , 9 } 判断A和B…

面试前赶紧看了5道Python Web面试题,Python面试题No17

目录 本面试题题库&#xff0c;由公号&#xff1a;非本科程序员 整理发布第1题&#xff1a; Flask中的请求上下文和应用上下文是什么?第2题&#xff1a;django中间件的使用&#xff1f;第3题&#xff1a; django开发中数据做过什么优化&#xff1f;第4题&#xff1a; 解释一下…

最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面

最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面。 原则 1.一致性 如果你可以在一个列表的项目上双击后能 够弹出对话框&#xff0c;那么应该在任何列表中双击都能弹出对话框。要有统一的字体写号、统一的色调、统一的提示用词、窗口在统一的位置、按钮也在窗…

Ant Design Vue中a-select组件下拉列表在局部滚动时不跟随问题解决方法

问题如下&#xff1a; 修改方法如下 <a-tree-select:getPopupContainer"triggerNode > {return triggerNode.parentNode || document.body;}"style"width: 100%":dropdownStyle"{ maxHeight: 400px, overflow: auto }":treeData"tree…

ospf路由汇总的目的

ospf路由汇总的目的减少网络中lsa传输的数量&#xff0c;减少网络中的变化&#xff0c;减少链路状态数据库&#xff0c;减少路由表&#xff0c;大大提高数据包查表转发的能力&#xff0c;能减少因为链路状态数据库的变化而引起的spf算法的重计算。转载于:https://blog.51cto.co…

第九周学习笔记

聚合&#xff1a; 1.当聚集函数遇到空值时&#xff0c;除COUNT(*)外&#xff0c;都跳过空值而出处理非空值。 2.WHERE子句中不能使用聚集函数。 3.聚集函数只能用于SELECT和GROUP BY中的HAVING语句。 常用的聚合函数 1 count 2 sum 3 avg 4 max 5 min 使…

2019年5月26日

距离考核结束的时间只剩下5天了&#xff0c;一个特别大的问题就是前后端的交流问题&#xff0c;不单单是项目的进度&#xff0c;更多的是人与人之间的交流。页面的进度完成了一整个流程&#xff0c;剩下的就是和后端的进行交互&#xff0c;后端的进度有点慢&#xff0c;导致我现…

Django3.0 +Python3 连接mysql遇到django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer

使用idea 创建了一个Django项目&#xff0c;不想使用默认的数据库进行操作&#xff0c;想切换成mysql数据&#xff0c;在此遇到了一些问题特此记录。 按照网上所说使用pymysql进行数据库连接操作&#xff0c;安装并且配置完毕后&#xff0c;在执行数据迁移操作时报错 django.…

栈的push、pop序列

题目&#xff1a;输入两个整数序列。其中一个序列表示栈的push顺序&#xff0c;判断另一个序列有没有可能是对应的pop顺序。为了简单起见&#xff0c;我们假设push序列的任意两个整数都是不相等的。 比如输入的push序列是1、2、3、4、5&#xff0c;那么4、5、3、2、1就有可能是…

const常对象成员与常成员函数

#include <iostream>#include <string>using namespace std;class pt{public:   pt(int a,int b){this->xa,this->yb;}   int getX() const {return this->x;} //此处必须加const&#xff08;关键&#xff09;&#xff0c;否则A.getX()将无法正常调用…

根据CPU核数合理设置线程池大小

一般来说池中总线程数是核心池线程数量两倍&#xff0c;只要确保当核心池有线程停止时&#xff0c;核心池外能有线程进入核心池即可。 我们所需要关心的主要是核心池线程的数量该如何设置。 自定义线程池代码 package com.lc.concurrent; import java.util.concurrent.ArrayB…

云答题微信小程序 实现 前端加后台管理

1.为什么要使用微信云开发 微信云开发自己是不需要域名&#xff08;备案的域名&#xff09;&#xff0c;服务器&#xff0c;搭建数据库等。 2.使用技术 微信小程序相关云接口java &#xff08;SpringBootMaven&#xff09;后台管理使用 VUE 3.实现微信小程序效果如下 微信小…

用Windows Media Player截图的方法

视频截图方法&#xff1a; 关闭“视频加速功能即可”。 以Windows Media Player 9.0为例&#xff0c;选择菜单“工具→选项”&#xff0c;找到“性能”选项卡中的“视频加速”一栏&#xff0c;然后拖动下方的拉杆将默认的“完成”改为“无”&#xff0c;按“确定”保存设置&…

基于OHCI的USB主机 —— 结束语

从去年11月份开始连载的《基于OHCI的USB主机》系列总算告一段落了&#xff0c;到UFI命令层为止&#xff0c;所有USB主机的底层处理就结束了&#xff0c;再上面就是磁盘读写、文件系统、文件读写和应用系统了。这些上层应用基本上是与USB主机没有什么关系的&#xff0c;我的这个…

mac os x 查看网络端口情况

查看端口是否打开 使用 netstat 命令 a. netstat -nat | grep <端口号> , 如命令 netstat -nat | grep 3306 b. netstat -nat |grep LISTEN 使用 lsof 命令 # yongfu-pro at yongfu-pro.local in ~ [22:39:32] $ lsof -n -P -i TCP -s TCP:LISTEN COMMAND PID USER FD …

POJ1149-PIGS

1&#xff0c;从各个顾客到汇点各有一条边&#xff0c;容量就是各个顾客能买的数量上限。 2&#xff0c;在某一轮中&#xff0c;从该顾客打开的所有猪圈都有一条边连向该顾客&#xff0c;容量都是∞。 3&#xff0c;最后一轮除外&#xff0c;从每一轮的i号猪圈都有一条边连向下…

Center OS 离线安装Mysql5.7

1.相关资料准备 1.离线安装包下载 或者百度网盘 链接&#xff1a;https://pan.baidu.com/s/1oVP3u8GSaavxoJqKnvZPKg 提取码&#xff1a;vw88 2.libao库文件下载 链接&#xff1a;https://pan.baidu.com/s/12hrQIEF3kk2h2HlWE41G7w 提取码&#xff1a;fvt8 2.开始安装 检…

offsetTop,clientX,clientTop,clientWidth,offsetWidth 坐标,一次弄明白

这几个属性都是IE火狐完全兼容的&#xff0c;不多说&#xff0c;看我测试结果便知&#xff1a; 【源码如下】 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ht…

各小组对于自己产品的预期“软件下载/用户人数”

组号 预期下载/用户人数Team1 100Team2 1000Team3 30下载&#xff0c;20篇博客引用Team4 1000Team5 3000Team6 100Team7 600Team8 1000下载&#xff0c;50个搜索结果引用Team9 300Team10 500在产品发布之后&#xff0c;再比照这个期望值&…

DB2 9 使用拓荒(733 检讨)认证指南,第 2 部分: DB2 数据操作(6)

学习根柢根底观观点操作游标游标措置概述在本节中&#xff0c;您将更进一步看到若安在嵌入式 SQL 使用次第中运用游标。异常&#xff0c;根柢根底的步骤照旧是声明、翻开、获取、更新/删除&#xff08;可选&#xff09;和封闭。为了赞助看法游标的观观点&#xff0c;假定 DB2 构…

判断字符串有无汉字

判断字符串是否全为汉字 1 String str1 "java判断是否为汉字" 2 String str2 "全为汉字" 3 String reg "[\\u4e00-\\u9fa5]" 4 boolean result1 str1.matches(reg)//false 5 boolean result2 str2.matches(reg)//true 提取字符串中…

获取指定字符的宽度

https://www.cnblogs.com/gaodu2003/archive/2009/06/12/1502242.html 方法一&#xff1a;var CharX, CharY: Integer;with Canvas do begin Font.Name : 宋体; Size : 9; CharX : TextExtent(字符串).cx; //字符串宽度&#xff0c;单位为像素 CharY : TextExtent(字符…

选课微信小程序开发 java

1.使用技术 javaspringbootmysqlhibernate微信小程序 2.功能介绍 后台管理 学生管理课程管理类型管理选课管理操作中心管理员中心导入导出学生微信小程序端 学生端 查看课程选课查看选课课程表个人中心管理员 查看课程新增课程用户管理课程类型管理管理员中心 3.系统功能展示…

危险进程大集合咯!(吐血推荐)

一般电脑中都有20-33个进程在后台运行着。有的占用了太多的系统资源&#xff0c;造成机器运行缓慢。更为不幸的是&#xff0c;一些进程是间谍软件和***&#xff0c;如此你的隐私和机器的控制权会被***所掌控。 不安全风险进程A 180ax.exe 是注册为TROJ.ISTZONE.H的下载器。这个…

老王Python-进阶篇4-异常处理1.3(周末习题)

一 编写with操作类Fileinfo()&#xff0c;定义__enter__和__exit__方法。完成功能&#xff1a; 1.1 在__enter__方法里打开Fileinfo(filename)&#xff0c;并且返回filename对应的内容。如果文件不存在等情况&#xff0c;需要捕获异常。 1.2 在__enter__方法里记录文件打开的当…

Springboot 日志管理模块编写记录

/**配置类 **/Component Order(value1) public class MyApplicationRunner implements ApplicationRunner{ /*private static final Logger logger LoggerFactory.getLogger(MyApplicationRunner.class);Autowiredprivate MemoryService memoryService; Overridepublic void r…