C# 简述.NET中堆和栈的区别

news2024/11/24 20:51:18

目录

一,引言

二,.NET的堆栈

三,.NET中的托管堆 

四,.NET中的非托管堆

五、堆栈、托管堆和非托管堆的比较

六,总结


一,引言

.NET提供了垃圾回收机制,使程序员从内存管理中被解放出来。但这并不代表程序员就无须了解分配的对象是如何被回收的。更重要的是,一些非托管的资源仍然需要程序员小心地分配与回收。

理解堆和堆栈是理解内存管理的基础。每一个.NET程序都最终会运行在一个操作系统进程中,假设这个操作系统是传统的32位的,那每个.NET程序都可以拥有一个4GB的虚拟内存。.NET会在这个4GB的内存块中开辟出三块内存分别作为堆栈、受托管的堆非托管的堆。

二,.NET的堆栈

.NET中的堆和栈用来存储值类型的对象和引用类型对象的引用,堆栈的分配是连续的。在.NET程序中,始终存储了一个特殊的指针指向堆栈的尾部,这样一个堆栈内存的分配就直接从这个指针指向的内存位置开始向下分配。下图展示了.NET的堆栈分配方式。

如上图所示,堆栈上的地址从高位开始往低位分配内存,.NET只需要保存一个堆栈指针指向下一个未分配内存的内存地址。对于所有需要分配的对象,依次分配到堆栈中,其释放也严格按照栈的逻辑,依次进行退栈。这里提到的“依次”,是指按照变量的作用域进行的。考虑下面的代码: 

ClassA a = new ClassA();
a.intA = 1;
a.intB = 2;

这里假设ClassA是一个引用类型,则堆栈中依次需要分配的是a的引用、a.intA和a.intB。当a的作用域结束后,这三个变量则从堆栈中依次退出:a.intB、a.intA,然后才是a。

三,.NET中的托管堆 

接下来我们看一下托管的堆。.NET中的引用类型对象是分配在托管堆上的。通常我们称.NET中的堆,指的就是托管的堆。和堆栈一样,托管的堆也是进程内存空间中的一块区域。但托管堆中的内存的分配却和堆栈有很大的区别。受益于.NET的内存管理机制,托管堆的分配也是连续的,但是堆中存在着暂时不能被分配却已经无用的对象内存块。当一个引用类型对象被初始化时,就会通过指向堆上可用空间的指针分配一块连续的内存,然后使堆栈上的引用指向堆上的这块内存块。下图展示了堆的分配方式。

如上图所示,程序通过分配在堆栈中的引用来找到分配在托管堆的对象实例。当堆栈区域中的引用退出作用域时,就仅仅断开引用和实际对象的联系。而当托管堆中的内存不够时,.NET开始执行垃圾回收。垃圾回收是一个非常复杂的过程,它不仅涉及托管堆中对象的释放,而且需要移动合并托管堆中的内存块。当垃圾回收后,堆内不被使用的对象才会被部分释放,而在这之前,它们在堆内是暂时不可用的。

四,.NET中的非托管堆

.NET的程序还包含了非托管的堆,所有需要分配堆内存的非托管资源将会被分配到非托管堆上。非托管的堆需要程序员用指针手动地分配并且手动地释放,.NET的垃圾回收和内存管理制度不适用于非托管的堆。

五、堆栈、托管堆和非托管堆的比较

堆栈、托管堆和非托管堆的分配各有特点。堆栈的内存是连续分配的,按照作用域依次分配和释放。

  • 堆栈的机制非常简单,.NET依靠一个堆栈指针就可以进行内存操作,分配一个对象和释放一个对象的大部分操作就是自增或者自减堆栈指针。.NET中的值类型对象和引用类型对象的引用是分配在堆栈内的。
  • 托管堆的内存分配虽然也是连续的,但它却比堆栈复杂得多。一块堆内存的分配需要涉及很多.NET内存管理机制的内部操作,另外当堆内存不够时,垃圾回收的执行代价也是非常大的。相对于堆栈来说,堆的分配效率低得多。.NET中的引用类型对象是分配在托管堆上的,这些对象通过分配在堆栈上的引用来进行访问。
  • 非托管堆和托管堆的区别在于非托管堆不受.NET的管理。非托管堆的内存是由程序员手动分配和释放的,垃圾回收机制不适用于非托管堆,内存块也不会被合并移动,所以非托管堆的内存分配按块的,不连续的。

六,总结

.NET程序在进程内存中分配出堆栈、托管堆和非托管堆。所有的值类型对象和引用类型对象的引用都分配在堆栈上,堆栈根据对象的生存周期来依次分配和释放,堆栈根据一个指向栈尾的指针来分配内存,效率很高。

.NET所有的引用类型对象分配在托管堆上,托管堆连续分配内存,并且受.NET的垃圾收集机制管理,受托管堆的内存分配和释放涉及复杂的内存管理,效率相对于堆栈来说低得多。

需要分配堆内存的非托管类型将被分配在非托管堆上,非托管堆不受.NET垃圾收集机制管理,内存块完全由程序员手动申请和释放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/725196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 语法详解之查找游戏物体的方法(含查找隐藏物体)

为了更好的看懂,有一个非常基础的知识,如果不知道可以移步去了解一下哦 unity | gameobject和transform的区别和关联通俗解释_gameobject transform_菌菌巧乐兹的博客-CSDN博客 一、前情提要 大写的GameObject是个类,里面写满了物体有关的…

python利用docxtpl将excel数据写入word表格

解决问题一:将excel数据读取,并将其保存在word中的表格 解决问题二:使用xlrd读入excel数据,如果是整数的话,打开word后发现保存变成了浮点数,后边多了“.0”。 问题一、 可以参考docxtpl快速上手使用,数…

电商API知识点整理(二)关键字搜索接口item_search获取商品列表

关键字搜索接口名称:item_search 接口背景: 随着互联网的普及和电子商务市场的快速发展,越来越多的消费者开始通过关键字搜索来寻找自己感兴趣的商品。为了满足用户的需求,电商平台开发了各种搜索接口,其中之一就是i…

22个最佳WordPress网站预约插件(2023)

您是否正在寻找可以节省您和您的客户时间的自动预订或预约插件?您是否厌倦了将业务输给竞争对手?您是否正在寻找一种简化在线预约和预订的方法? 您的网站应该让客人可以轻松查看和预订可用的预约。这是WordPress预约插件可以帮助您实现在线业…

基于Python的DES算法的企业用户数据安全加密系统设计与实现

博主介绍:擅长Java、微信小程序、Python、Android等,专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案例…

【SLAM14讲】04 三维空间刚体运动

一、坐标系之间的欧式变换 xW , yW , zW定义的世界坐标系,xC , yC , zC 定义的相机坐标系。 相机视野中某个向量 p,它的坐标为pc,而从世界坐标系下看,它的坐标 pw。 二、相机运动 相机运动是一个刚体运动,它保证了同…

golang arena

go 1.20新特性 goland设置 Enviroment 定义环境变量 Go tool arguments 就是go build 的参数 Program arguments 启动参数 GOEXPERIMENTarenas -tags goexperiment.arenas //go:build goexperiment.arenaspackage mainimport ("arena""fmt""net/…

可以实现语音录入的好用的记事本app是哪个?

在现代快节奏的工作生活中,记事本成为了人们不可或缺的工具之一。然而,传统的手写记事本已经无法满足人们快速、高效的需求,语音记事的好处不言而喻。 它不仅能够提高工作效率,减少输入时间,还能够帮助用户更好地记录…

使用Visual Studio 2019 编译Masscan

目录 使用Visual Studio 2019 编译Masscan 1.从github下载源码 2.安装Visual Stiudio 2019 3.准备编译Masscan 4.编译Masscan 总结 使用Visual Studio 2019 编译Masscan 1.从github下载源码 可以直接在GitHub上搜索,下载后的源码目录结构。 2.安装Visual Stiu…

ds1:java-stream流

文章目录 1.修改集合中的值map2.过滤集合中符合条件的值filter找集合中的最大/小的值,及操作后元素的个数max()/min()/count()归约:对集合中所有元素进行自定义计算获取最终值reduce()collect分组(partitioningBy/groupingBy)修改集合中元素之间的连接符…

ctr-k8s镜像管理命令,将k8s正在使用的镜像推送仓库

​ k8s镜像管理命令 查出k8s中pod在使用的镜像 kubectl get -o wide deploy -n yxyw-uat |awk ‘{print $7}’ 查出镜像地址,勾选正则开头配上镜像推送命令 gem-acr-p-a01-registry-vpc.cn-shenzhen.cr.aliyuncs.com/osale/gyx-admin:yxyw-pre-2023-06-05-11-18…

便携式多功能校准器TD1858参考标准

体积小巧:相较于同档次技术指标的多功能校准器,体积缩小至50%,重量轻便:整机质量不到10 kg,人员可轻松实现搬运,方案价值:非常方便携带至工作现场对数字多用表和其他电测仪表进行校准。 直流电压…

搭建cesium源码调试环境

1. cesium源码下载 直接从github上下载即可 https://github.com/CesiumGS/cesium.git 本文下载的是最新版本1.106 2. cesium源码目录简介 1) packages目录 源码目录,包含engine,widgets 2)Apps目录 包含一些示例代码 3)Spec…

Node中express路由基本使用

1.路由的基本使用 //引入express const expressrequire("express") //创建路由 const appexpress() //规定路由的请求方法 app.get(/,(req,res)>{res.end("hello express") }) //启动路由,并且端口为9000 app.listen(9000,()>{console.l…

ruoyi-vue版本(三十)事务介绍和使用

目录 1 事务管理2 常见坑点13 常见坑点24 Transactional注解的常用属性表: 1 事务管理 新建的Spring Boot项目中,一般都会引用spring-boot-starter或者spring-boot-starter-web,而这两个起步依赖中都已经包含了对于spring-boot-starter-jdbc…

和鲸社区数据分析每周挑战【第九十六期:汽车公司客户细分预测】

和鲸社区数据分析每周挑战【第九十六期:汽车公司客户细分预测】 文章目录 和鲸社区数据分析每周挑战【第九十六期:汽车公司客户细分预测】一、前言1、背景描述2、什么是用户分群?3、数据说明4、数据集预览 二、数据读取和数据初步观察三、潜在…

【动态规划算法】第六题:63.不同路径II

💖作者:小树苗渴望变成参天大树 🎉作者宣言:认真写好每一篇博客 🎊作者gitee:gitee 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作…

2、DuiLib的入门程序以及资源压缩打包

标题 1、DuiLib入门程序11.1、DuiLib程序版本11.2、DuiLib程序版本21.3、DuiLib程序版本3,增加编写界面xml1.4、DuiLib程序版本4,继续修改xml布局1.5、DuiLib程序版本5,继续修改xml布局5.6、DuiLib程序版本5,继续修改xml布局 2、D…

Stable Diffusion 使用 SadTalker 生成图片数字人

Heygen和D-ID等照片转视频的工具,都需要在线付费使用。本次介绍一个SadTalker数字人。SadTalker有多种使用方式,包括完整安装程序和stable diffusion插件模式。安装程序操作较繁琐,因此推荐stable diffusion插件模式。 文章目录 SadTalker安…

【龙芯2K500先锋板】点亮RGB多彩发光板

文章目录 一、硬件准备1.1 DFRobot RGB多彩发光板1.2 龙芯2K0500开发板 二、背景知识三、实现点灯3.1 手动点亮3.2 手动熄灭3.3 实现PwmController3.4 实现呼吸灯效果 四、效果演示五、完整代码六、参考链接 前段时间乔帮主送了几个DFRobot的RGB多彩发光板,官方的演…