浅谈C#中堆和栈的区别(附上图解)详解.docxVIP

浅谈C#中堆和栈的区别(附上图解)详解.docx

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
浅谈C#中堆和栈的区别(附上图解) C#中栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小 线程堆栈:简称栈 Stack 托管堆: 简称堆 Heap 使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切。如果我们写出如下两段代码: 代码段1: HYPERLINK /article/55306.htm ? 1 2 3 4 5 6 public int AddFive(int pValue) { int result; result = pValue + 5; return result; } 代码段2: HYPERLINK /article/55306.htm ? 1 2 3 4 5 6 7 8 9 10 11 public class MyInt {? public int MyValue; } ?? public MyInt AddFive(int pValue) { MyInt result = new MyInt(); result.MyValue = pValue + 5; return result; } 问题1:你知道代码段1在执行的时候,pValue和result在内存中是如何存放,生命周期又如何?代码段2呢? 要想释疑以上问题,我们就应该对.Net下的栈(Stack)和托管堆(Heap)(简称堆)有个清楚认识,本立而道生。如果你想提高程序性能,理解栈和堆,必须的! 本文就从栈和堆,类型变量展开,对我们写的程序进行庖丁解牛。 C#程序在CLR上运行的时候,内存从逻辑上划分两大块:栈,堆。这俩基本元素组成我们C#程序的运行环境。 一,栈 vs 堆:区别? 栈通常保存着我们代码执行的步骤,如在代码段1中 AddFive()方法,int pValue变量,int result变量等等。而堆上存放的则多是对象,数据等。(译者注:忽略编译器优化)我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走(called a Frame,译注:调用帧),接着下一个。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,跟栈不同的是他们被调用完毕不会立即被清理掉。 如图1,栈与堆示意图 (图1) 栈内存无需我们管理,也不受GC管理。当栈顶元素使用完毕,立马释放。而堆则需要GC(Garbage collection:垃圾收集器)清理。 二,什么元素被分配到栈?什么被分配到堆? 当我们程序执行的时候,在栈和堆中分配有四种主要的类型:值类型,引用类型,指针,指令。 值类型: 在C#中,继承自System.ValueType的类型被称为值类型,主要有以下几种(CLR2.0中支持类型有增加): * bool * byte * char * decimal * double * enum * float * int * long * sbyte * short * struct * uint * ulong * ushort 引用类型: 以下是引用类型,继承自System.Object: * class * interface * delegate * object * string 指针: 在内存区中,指向一个类型的引用,通常被称为“指针”,它是受CLR( Common Language Runtime:公共语言运行时)管理,我们不能显示使用。需要注意的是,一个类型的引用即指针跟引用类型是两个完全不同的概念。指针在内存中占一块内存区,它本身只代表一个内存地址(或者null),它所指向的另一块内存区才是我们真正的数据或者类型。如图2: (图2) 指令: 后文对指令再做介绍。 三,如何分配? 我们先看一下两个观点: 观点1,引用类型总是被分配在堆上。(正确?) 观点2,值类型和指针总是分配在被定义的地方,他们不一定被分配到栈上。(这个理解起来有点难度,需要慢慢来) 上文提及的栈(Stack),在程序运行的时候,每个线程(Thread)都会维护一个自己的专属线程堆栈。 当一个方法被调用的时候,主线程开始在所属程序集的元数据中,查找被调用方法,然后通过JIT即时编译并把结果(一般是本地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以执行下去。 下面我们以实例来详谈。 还是我们开篇所列的代码段1: HYPERLINK /article/55306.htm ? 1 2 3 4 5 6 public int AddFive(int pValue) { i

文档评论(0)

cc880559 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档