堆栈与托管堆

堆栈和托管堆 c#   装箱转化using System;class Boxing{  public static void Main()  { int i=110;    object obj=i;    i=220;    Console.WriteLine("i={0},obj={1}",i,obj);    obj=330;    Console.W 阅读详情

这是雨痕的的文章,原文在这里。

关于 CLR 内存管理模式,各种书籍和网络文章各执一词,十分混乱。大多数时候也只是泛泛提到 "托管堆" 和 "堆栈" 而已,其实际过程非常复杂。鉴于没有一个统一的说法,我也不能保证本文的准确性。

当 CLR 创建执行线程时,会依据 mainfest 中的 ".stackreserve 0x00100000" 指令为当前线程分配 1MB 的调用堆栈(Call Stack)内存。调用堆栈不同于托管堆(Managed Heap),它不负责保存托管引用对象,只是用来维护方法调用次序,执行 IL 指令。而当我们使用 call、callvirt 等指令调用一个方法时,CLR 会在调用堆栈中分配一个称之为堆栈帧(Stack Frame) 的内存块用于执行目标方法代码。下图就是一个堆栈帧的内存示意图。

http://www.rainsts.net/uploads/200710/05_233621_1.gif



如图所示,每个堆栈帧中包含三块内存:参数表 (Argument Table) 用于存储方法参数,内部变量表 (Local Variable Table) 存储方法局部变量(.locals init),而 计算堆栈 (Evaluation Stack) 则是 IL 代码执行区域。执行 IL 指令前,相关指令数据(Data)或其地址(Address)被压入计算堆栈,然后执行指令并弹出计算结果,执行下一个指令时继续重复这样的动作,直到方法调用结束。这三部分内存共同构成了一个方法的内存执行环境,需要注意的是其大小单位并不是 byte,而是 slot。每个 slot 可以存储一个托管单元(对象),我们可以在方法体中使用 .maxstack 指令控制当前方法计算堆栈的大小。

.method private hidebysig static void Test1(int32& x) cil managed
{
  .maxstack 8
}


回到方法调用流程,当我们使用 call 等指令调用一个方法时,CLR 为目标方法在调用堆栈上新分配一个堆栈帧,并将方法参数从当前方法的计算堆栈弹出压入目标方法的参数表中,接着执行流程跳转到目标方法。当执行 .locals init 指令时,会在其内部变量表中创建相应的内部变量,然后使用目标方法的计算堆栈完成 IL 指令执行。当目标方法 IL 指令结束时,其返回值(如果有)会被弹出(pop)并压入(push)最初调用者的计算堆栈中,ret 指令将控制权返回给调用者,目标方法堆栈帧被抛弃,所占用内存被释放。

相关概念

栈(Stack)和堆(Heap)不同,它是一种线性结构,而堆是一种链式结构。栈按照先进后出 (LIFO - Last In First Out) 的原理工作,通过一个指针来维护内存占用。当我们释放一段内存时,只要将指针回复到某个起始位置即可,因此它的执行效率非常高。而托管堆(Managed Heap)是动态分配的内存区域,由 GC 进行管理,每个进程中的所有线程共享一个托管堆。

.NET CLR 和 Java VM 都是一种被称之为堆栈式虚拟机(Stack-Base VM)的技术,它的执行机制和我们所熟悉的 80x86 执行方式有所不同,它并没有寄存器的概念,他们的指令集(Instruction Set) 都是采用堆栈进行运算,首先将数据(Data)压入栈,然后进行操作。此处的堆栈就是我们上面所说的计算堆栈(Evaluation Stack)。

堆栈和托管堆的详解堆栈和托管堆的详解 堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解堆栈和托管堆的详解 立即下载

相关推荐

【COMSOL】修改内置物理场方程 模拟水沸腾的蒸汽泡运动

在COMSOL中通过弱贡献(weak contribution)节点,可以向任何内置模型方程中添加约束。这里,以模拟水沸腾的蒸汽泡运动为例,来讲一讲当我们研究的方程与模块方程不一样时,应该怎么增加新的贡献项。

u012161192的博客 9008

IL语言(一)-HelloWorld解析

IL语言(也称为公共中间语言CIL,或微软中间语言MSIL)是.NET的核心,以.NET Framework平台运行的程序最终都是由IL代码实现。也可以这样理解,无论C/C++、BASIC、Pascal等语言特征如何,在INTEL芯片上最终执行的都是Intel汇编指令集。了解IL相关知识能够以较高层次理解.NET工作原理,最大程度利用.NET Framework进行高级程序开发。 1、能更好地理

阿满工作室 2434

Backtrader 文档学习- 整体架构功能分析理解

backtrader是一个用于开发和执行交易策略的Python框架。它提供了一套完整的工具和功能,使得用户可以方便地进行策略回测、实盘交易以及数据分析。backtrader的入口为Cerebro类,该类将所有输入(Data Feeds)、策略 (Strategy)、观察者(Observers)、策略评估(Analyzers) 、经纪人(Broker)、订单(Order)、交易(Trade)和日志记录(Writers)整合起来,实现回测以及交易,并返回结果和图表。

六月闻君 6327

C#的内存管理:堆栈、托管堆与指针 (转)

在32位的Windows操作系统中,每个进程都可以使用4GB的内存,这得益于虚拟寻址技术,在这4GB的内存中存储着可执行代码、代码加载的DLL和程序运行的所有变量,在C#中,虚拟内存中有个两个存储变量的区域,一个称为堆栈,一个称为托管堆,托管堆的出现是.net不同于其他语言的地方,堆栈存储值类型数据,而托管堆存储引用类型如类、对象,并受垃圾收集器的控制和管理。在堆栈中,一旦变量超出使用范围,其使用...

weixin_30617561的博客 634

从零到一:手把手部署用友T3标准版11.2及SQL Server 2008R2环境

本文详细介绍了从零开始部署用友T3标准版11.2及SQL Server 2008R2环境的完整流程,包括环境准备、SQL Server安装、环境检测与修复、T3标准版安装实战以及初始化配置与测试。通过手把手的步骤指导和常见问题解决方案,帮助用户顺利完成部署,确保系统稳定运行。

weixin_28339967的博客 454

【机器人】线性方程最小二乘解法对机械臂DH参数进行标定

1.前言 看了一篇文章,觉得里面的DH参数标定法讲的很清晰,便使用Matlab复现了一下,效果还可以,特写此文记录。 2.原理 2.1.误差最佳值的最小二乘计算 有研究结果表明:几乎95%的机器人位置误差都是由机器人内部运动学的不准确描述引起的,所以对DH模型参数进行标定是很有必要的。 DH参数物理含义:选自《机器人学、机器视觉与控制-Matlab基础》 当DH参数确定后,我们...

要恰饭得嘛 1万+

托管堆与堆栈

内存格局通常分为四个区   全局数据区:存放全局变量,静态数据,常量   代码区:存放所有的程序代码   栈区:存放为运行而分配的局部变量,参数,返回数据,返回地址等,   堆区:即自由存储区 值类型变量与引用类型变量的内存分配模型也不一样。为了理解清楚这个问题,读者首 先必须区分两种不同类型的内存区域:线程堆栈(Thread Stack)和托管堆(Managed Heap)。 每个

Lyncai的专栏 3285

Open FPV VTX与Betaflight的MSP协议配置详解:从硬件连接到OSD显示

本文详细解析了如何通过MSP协议将Open FPV VTX与Betaflight飞控进行深度集成,实现飞行数据在OSD上的稳定显示。内容涵盖从硬件连接、Betaflight端口MSP服务启用,到VTX侧配置与OSD元素布局调校的全流程,并提供了常见问题的排查思路,帮助FPV玩家构建可靠的数据叠加系统。

weixin_29201933的博客 452

C# 堆和栈

C#中堆栈详解

Love_HBB的专栏 3173

模组 RG500Q入网问题分析

- [ ] 不同于公网,在5G专网环境中, 通常使用很多非标准的网络配置,如PLMN/APN等。因此,5G模组在专网环境下通常要做一些专门的配置才能正常入网,本文分析一例在专网环境, 5G终端无法入网问题的定位过程。 - [ ] 具体涉及到以下模组操作: 恢复出厂、SA only、锁BAND、配置MBN等

十年通信老兵的技术修炼之路——从3G到5G,从地面基站到卫星通信。 935

Vibe Coding 工具实战案例全解:Cursor、Claude Code、Codex 真实项目 30 分钟到 4 小时快速构建指南(2026 年最新)

2026年VibeCoding工具实战案例精选:1)使用Cursor在30分钟内构建现代TodoList应用(Next.js+TS+Tailwind);2)通过ClaudeCode纯终端2小时开发3D飞行射击游戏(Three.js+R3F);3)利用OpenAICodex多Agent并行4小时完成SaaS全栈开发(Next.js+Supabase+Stripe)。案例均来自真实项目,覆盖从入门到生产级开发,重点展示:自然语言Prompt技巧、迭代反馈方法、工具特性对比(Cursor可视化最佳/Claude推

hy行者勇哥的博客 3173

堆栈和托管堆

引用博客:https://www.cnblogs.com/shenfengok/archive/2011/09/06/2169306.html

ILOVE鸽的博客 155

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C#堆栈及托管堆的内存创建机制

堆栈的地址是从高到低的,托管堆的地址是从低到高的。这个部分的创建制止与类的继承本质直接相关,在与创建GC堆内类字段的时候的递归创建以及创建方法表时候的递归创建。  这里对与类成员方法相关的几个关键字:例如abstract , new , override做简单的描述。  方法表先于类型句柄产生。产生过程中,与类成员变量继承时的递归空间分配大同小异。在与几个关键字的处理上略有区别。  对于abstract关键字,在父类中出现,在子类中必须被覆盖,也就是在子类中由override关键字将其覆盖。(过程是递归的,

WInScar的专栏 1559

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C#垃圾回收和托管堆及堆栈

堆栈和托管堆: 首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型。 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充。 堆栈的工作方式是先分配内存的变量后释放(先进后出原则)。 堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突! 堆栈的性能非常高,但是对于

lin37985的专栏 2780

c# 托管堆,堆栈【图文非常详细】

转载地址:http://blog.csdn.net/baoxuetianxia/article/details/3218913 装箱转化 using System; class Boxing {   public static void Main()   { int i=110;     object obj=i;     i=220;     Console.WriteLine

天外有天,人外有人。 专注品质 不断创新 让精益求精成为习惯 908

C# 堆栈与堆(托管堆)

首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型。 堆栈实际上是向下填充,即由高内存地址指向地内存地址填充。 堆栈的工作方式是先分配内存的变量后释放(先进后出原则)。 堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突! 堆栈的性能非常高,但是对于所有的变量来说还不...

awwiia8806的博客 125

深入理解 c#堆栈和托管堆

【转】堆栈和托管堆 c# 原文地址:http://blog.csdn.net/baoxuetianxia/archive/2008/11/04/3218913.aspx 首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型。 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充。 堆栈的工作方

liu_ben_qian的专栏 1万+

类型,对象,堆栈和托管堆

C#的类型和对象在应用计算机内存时,大体用到两种内存,一个叫堆栈,另一个叫托管堆,下面我们用直角长方形来代表堆栈,用圆角长方形来代表托管堆。 首先讨论一下方法内部变量的存放。 先举个例子,有如下两个方法,Method_1和Add,分别如下: public void Method_1() { int value1=10;  //1 int value2=2...

144

C#托管堆,堆栈(图文非常详细)

首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型; 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充。 堆栈的工作方式是先分配的内存变量后释放(先进后出原则)。 堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突。 堆栈的性能非常高,但是对于所有的变量来说...

weixin_30338497的博客 244
上一篇: Visual Studio 2010 Beta 1 发布了
下一篇: 如何设置结构中只读属性的值
CsToD
博客等级 码龄19年 91粉丝 35原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值