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

目录

一,引言

二,.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垃圾收集机制管理,内存块完全由程序员手动申请和释放。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4.2 x64dbg 针对PE文件的扫描

通过运用LyScript插件并配合pefile模块,即可实现对特定PE文件的扫描功能,例如载入PE程序到内存,验证PE启用的保护方式,计算PE节区内存特征,文件FOA与内存VA转换等功能的实现,首先简单介绍一下pefile模块。 …

【Web3】Web3连接到以太坊网络(测试网、主网)

目录 什么是Web3 Web3项目连接以太坊网络 1.下载Web3 2.实例化Web3对象 3.infura 获取连接以太坊网络节点 4.添加网络节点 什么是Web3 web3.js开发文档:web3.js - Ethereum JavaScript API — web3.js 1.0.0 documentation web3.js 中文文档 : web3.js - 以…

Mysql 幻读,当前读和快照读

什么是幻读 幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户在读取该范围的数据行时,会发现有新增行数据; mysql 在RR(可重复读)隔离级别利用间隙锁机制下一定程度上解决了幻读。 这里的一定程度…

Android Studio实现内容丰富的安卓美食管理发布平台

如需源码可以添加q-------3290510686,也有演示视频演示具体功能,源码不免费,尊重创作,尊重劳动。 项目编号079 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端: 1.注册登录 2.查看公告 3.查…

更改VS code Jupyter 插件的默认快捷键

更改vscode 中Jupyter插件的默认快捷键,解放插入空行的系统快捷键 替换Jupyter默认快捷键 更改vscode 中Jupyter插件的默认快捷键,解放插入空行的系统快捷键打开keyboard shortcuts 设置方法一方法二 更换快捷键 end Jupyter 插件很好的在VS code中集成了…

异地远程访问本地SQL Server数据库【无公网IP内网穿透】

文章目录 1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 转载自cpolar极点云文章:无需公网IP…

Golang的trace性能分析

文章目录 一、trace概述二、trace的使用方式代码中trace采集通过pprof采集 三、trace分析细节trace的web界面trace中需要关注的关注GC的频率关注goroutine调度情况关注goroutine的数量理想情况 四、GC分析当前服务GC情况设置GOGC设置GOMEMLIMITGC阈值的讨论GC的特点 五、gorout…

前端学习——jsDay5

对象 对象使用 小练习 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"width…

Spring Boot中的请求参数绑定及使用

Spring Boot中的请求参数绑定及使用 在Web应用程序中&#xff0c;请求参数绑定是非常重要的操作。Spring Boot框架使得请求参数绑定变得非常简单&#xff0c;通过使用注解和预定义的类可以轻松地实现此操作。本文将介绍Spring Boot中的请求参数绑定及其使用。 请求参数绑定 在…

银河麒麟服务器v10 sp1 部署 Net6.0 项目

上一篇已经部署了Net6.0环境&#xff0c;本节将实现Net6.0程序部署&#xff0c;打开或新建项目&#xff0c;修改appsettings.json配置&#xff1a; 添加&#xff1a;"urls": "http://*:8061",//linux部署使用&#xff0c;端口可根据需求修改为自己的 在项…

关于数据库SQL优化

简介 在项目上线初期&#xff0c;业务数据量相对较少&#xff0c;SQL的执行效率对程序运行效率的影响可能不太明显&#xff0c;因此开发和运维人员可能无法判断SQL对程序的运行效率有多大。但随着时间的积累&#xff0c;业务数据量的增多&#xff0c;SQL的执行效率对程序的运行…

简要介绍 | 基于深度学习的姿态估计技术

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对基于深度学习的姿态估计技术进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 注2&#xff1a;"简要介绍"系列的所有创作均使用了AIGC工具辅助 基于深度学习的姿态估计技术 背景介绍 …

前端 | windows安装nvm管理node.js

文章目录 01 nvm介绍02 安装03 设置镜像04 安装与版本管理05 基础使用 01 nvm介绍 nvm&#xff0c;即node version manager&#xff0c;是一个方便切换和管理node.js版本的工具。 安装nvm前的注意事项&#xff1a; 卸载掉现有的node.js所有安装目录避免出现空格和中文选用管理…

用vue3+elementplus做的一个滚动菜单栏的组件

目录 起因概览设计及解决思路1.滚动条竖起来2.绑定菜单3.吸附优化 组件全部代码 起因 在elementplus中看到了滚动条绑定了slider&#xff0c;但是这个感觉很不实用&#xff0c;在底部&#xff0c;而且横向滚动&#xff0c;最常见的应该是那种固定在左上角的带着菜单的滚动条&a…

Windows 10睡眠失效解决办法

第一步 检查是否有程序阻止睡眠 打开终端,执行如下命令 powercfg /requests如果返回结果不为空说明有程序阻止睡眠 找到对应的程序将其退出即可 如果返回结果为空则进行下一步 第二步 检查网易UU加速器 如果你安装了UU加速器 打开网易UU加速器 打开系统设置,将休眠不断…

MySQL压测实战

写作目的 最近看到一句话是MySQL的TPS是4000&#xff0c;这句话是不严谨的&#xff0c;因为没有说服务器的配置。所以自己买了个服务器做了一个压测。希望自己对数据有一个概念。 注意&#xff1a;服务器不同结果不同&#xff0c;结果不具有普适性。 服务器配置 配置参数CPU…

【数据结构】堆的实现(向下调整和向上调整法)和堆排序的实现

目录 一、堆的概念引入 二、小堆的实现 首先&#xff0c;我们会跟线性表一样建立一个动态数组来存堆的数据 ①、堆的初始化--HeapInit ②、小堆的向下调整法的实现 ③、堆排序的实现 ④、堆的插入和向上调整法 ⑤、删除堆顶数据 ⑥、获取堆顶 三、时间复杂度总结&#…

网络安全进阶学习第六课——服务器解析漏洞

文章目录 1、概念2、Apache解析漏洞 CVE-2017-157153、Apache AddHandler解析漏洞4、IIS6 解析漏洞&#xff08;;&#xff09;5、IIS6 解析漏洞&#xff08;*.asp/目录&#xff09;6、IIS7 解析漏洞&#xff08;ISAP或CGI的模式下&#xff09;7、nginx解析漏洞&#xff08;cgi.…

2023年6月第4周大模型荟萃

2023年6月第4周大模型荟萃 2023.6.30版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、腾讯云首次公布大模型进展 6月19日&#xff0c;腾讯云召开行业大模型及智能应用技术峰会&#xff0c;首次公布腾讯云行业大模型研发进展&#xff0…

QT下载太慢,在线安装太慢的解决方案

实现效果 步骤1 下载在线安装的客户端&#xff0c;可以从qt.io&#xff08;qt-unified-windows-x64-4.6.0-online.exe&#xff09;下载&#xff0c;速度稍慢&#xff0c;但是大小也才38MB左右。 觉得下载太慢的小伙伴可以使用我提供的代下载版本&#xff0c;你们可以校验文件…