(转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
2014-02-24 21:20
781 查看
转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html
在.NET程序运行过程中,什么是堆,什么是栈?堆也就是托管堆(managed heap),进程初始化的时候,CLR要保留一块连续的地址空间,这个地址空间最初并没有对应的物理存储空间。这个地址空间就是托管堆。
栈是在程序运行过程中用于保存指令,值类型变量的内存区域(一个线程对应一个栈),栈的结构和数据结构中“栈”的结构是一样的,“先进后出”。
什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?
值类型在栈上分配,引用类型在堆上分配。由于在栈上分配数据不受垃圾回收的控制,不存在垃圾回收的各种开销,应用程序执行的时候垃圾回收的次数也会少很多,所以栈上分配显然要比堆上分配性能上好。由于在栈上分配的变量已经包含了实例的字段所以不需要一个指针指向它。空间上的开销也较小。
“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
这点不是太明确:值类型不作为对象在堆中分配。但在许多情况下,都需要获取对值类型的一个实例引用。例如假定要建个ArrayList来容纳Point结构。
//声明一个值类型。 struct Point { publicint x, y;} publicsealedclass Program { publicstaticvoid Main() { ArrayList a =new ArrayList(); Point p; for (int i =0; i <10; i++) { p.x = p.y = i; a.Add(p); } } }
这个时候 Point 值类型必须转换成一个真正 的,在堆中托管的对象,而且必须 获取对这个对象的引用。 这就是装箱的机制。 (不知道老赵说的是不是这种情况,还望老赵予以解答,还希望知道的朋友探讨下是不是这种情况)
下面是装箱的过程:
1.在托管堆中分配好内存。分配的内存是值 类型的各个字段需要的内存量加上托管的所有对象都 有的两个额外成员(类型对象指针和同步索引)需要的内存量。
2 值类型的字段复制到新分配的内存
3 返回对象的地址。现在,这个地址是对一个对象的引用,值类型现在是一个引用类型。
在运行时,当前存在于Point 值类型的实例P中的字段会复制到新分配的Point对象中。已经装箱的Point 对象(现在是一个引用类型)的地址会返回给Add方法。Point对象会一直存在于堆中。
如果是这种情况那么需要注意的地方就:这样会产生装箱/ 拆箱的操作。建议用泛型集合类。 FCl现在包含一组泛型集合类。这样不需要对集合中的项进行装箱、拆箱的处理,使性能提高不少,托管堆中需要创建的对象减少了,减少了应用程序中需要执行的垃圾回收次数。
最后一点还希望知道的朋友确认下,也希望老赵能确认下。
相关文章推荐
- 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?
- (转)类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?
- 选择login_activity作为程序运行的入口需要注意的情况
- 如果修改了表结构的话,可能也需要将调用到表的存储过程、函数等也修改一下,以下语句可以查询到那些对象调用到被修改的表
- 建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内 如果需要在循环中引发异常,你需要特别注意,应为抛出异常是一个相当影响性能的过程。应该尽量在循环当中对异常发生的一
- 考虑下列生成二进制的过程,编译器被用来生成单个单元的目标代码,链接器被用来将多个目标单元合并成一个程序二进制,链接器如何改变指令和数据到内存地址的绑定?需要什么信息从编译器传递给链接器,以协助完成链接
- 开发S60 3rd开机后台运行的程序需要注意些什么?
- VB.net 简单程序的结构 (注意和VB过程的区别)
- 程序运行时,对象是怎么进行放置的呢?特别是内存是怎么分配的呢?对这些方面的了解会对你有很大的帮...
- 程序开发,数据变量常量对象等保存到什么地方?
- new/delete和malloc/free的区别,并说说你在什么情况下会自另行建立自己的内存分配。
- 深拷贝和浅拷贝的区别?如果要delete一个浅拷贝,需要注意什么条件?
- 程序运行时 0xC0000005: 读取位置 0x00000000 时发生访问冲突 ,可能是 com 组件引入各种问题
- 一次 read by other session 的处理过程--数据走索引需要看索引字段的数据分布情况
- .NET-WEB网站部署的过程中需要注意的问题
- .net下导致Session失效的一种情况:js教本中使用window.open和window.showModalDialog时需要注意
- 面向过程(面向结构)与面向对象的区别
- 关于2003Server下IIS运行.net程序IE无法访问出现403.1错误的解决过程
- 研究一下对象的实例化过程发生了什么
- .net下导致Session失效的一种情况:js教本中使用window.open和window.showModalDialog时需要注意