(转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?
转自: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现在包含一组泛型集合类。这样不需要对集合中的项进行装箱、拆箱的处理,使性能提高不少,托管堆中需要创建的对象减少了,减少了应用程序中需要执行的垃圾回收次数。
最后一点还希望知道的朋友确认下,也希望老赵能确认下。
(转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?的更多相关文章
- 程序运行过程中遇到“ORA-03114: not connected to ORACLE”的问题解决
c#,winform程序,数据批量入oracle库时用到DataAdaper的.FillSchema函数,如:da.FillSchema(dt2, SchemaType.Mapped); 程序运行一段 ...
- Java 程序运行过程中的内存分析
作为 java 程序员,都应该知道 Java 程序运行在 JVM(Java Virtual Machine,Java 虚拟机)上,可以把 JVM 理解成 Java 程序和操作系统之间的桥梁,JVM 实 ...
- [转载] linux 程序运行过程中替换文件
今天被朋友问及“Linux下可以替换运行中的程序么?”,以前依稀记得Linux下是可以的(而Windows就不让),于是随口答道“OK”.结果朋友发来一个执行结果:(test正在运行中)# cp te ...
- robot framework程序运行过程中,遇到点击事件之后,未出现点击之后的效果(求解)
1.click Element操作,在实际过程中偶然会出现,日志显示已点击成功,但是实际自动化页面,没有点击成功之后的操作 现象: 现象描述:程序执行到点击侧边栏的[人员信息]之后,日志显示已经点击成 ...
- 放在NSArray、NSDictionary等容器内的对象Item,Item中的property在程序运行过程中被无故释放
可能是被释放的property本身是OC对象而它的属性被误写成assign,例如: @interface MyItem : Object @property (nonatomic, assign) N ...
- STM32在程序运行过程中关闭定时器重新打开后定时器不工作的问题
问题:数码管显示程序放在定时TIM2中断函数里面扫描,想要实现在关闭某一功能的时候数码管不显示. 刚开始的想法是开关关闭,关闭定时器时钟:开关打开,打开定时器时钟:(但实验证明再次打开开关时定时器2却 ...
- Java内存管理-程序运行过程(一)
勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 相信在做Java开发的伙伴一定知道 JVM(Java Virtual Machine( ...
- opencv检错:程序运行过程正常,当跳出函数时出现断言错误(Debug Assertion Failed)
转载http://blog.csdn.net/u012327581/article/details/51351780 1.问题描述 在VS2015下配置好Opencv后,程序在函数运行过程中正常,调试 ...
- java 程序运行过程 简介
这里的Java程序运行过程,是指我们编译好代码之后,在命令行开始执行java xxx命令,到java程序开始执行起来的这一过程,我们称其为运行时. 第一步,操作系统解析我们输入的java xxx命令, ...
随机推荐
- XP下1433端口打不开
问题:操作系统windows xp:数据库sql server 2000:安装后通过程序无法访问数据,原因是数据库的默认端口1433未打开. 原因:sql server 2000的bug,需要升级补丁 ...
- 引入flash
调用代码 <div class="media"> <object class="main_video_box" classid="c ...
- jQuery Dom对象操作 增、删、改、复制、包裹
1. 增(插入) 内部插入 //向每个匹配的元素内部追加内容,为最后一个子元素$('.violet').append('<div></div>'); //把所有匹配的元素追加到 ...
- 错误:在非结构或联合中请求成员‘next’
#include <stdio.h> #include <stdlib.h> #define ElemType int #define Status int #define O ...
- [网络流]Drainage Ditches(草地排水)
Drainage Ditches(草地排水) 题目描述 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰 ...
- Linux 中的文件锁
参考资料: https://www.ibm.com/developerworks/cn/linux/l-cn-filelock/index.html
- the example of dlsym
void *handle; int i, (*fptr)(int); /* open the needed object */ handle = dlopen("/usr/home/me/l ...
- Eclipse的下载及安装
Eclipse的下载地址: https://www.eclipse.org/downloads/ 下载完成后,双击安装包即可安装 选择 Eclipse IDE for Java EE Decelope ...
- &和&&的区别是什么
1)&是按位与操作符,a&b是把a和b都转换成二进制数后,然后再进行按位与的运算.&&是逻辑与运算符,a&&b就是当且仅当两个操作数都为true时,其结 ...
- sqli-labs:17,增删改
增 insert into users values(','lcamry','lcamry'); 删 delete from users where id=16 删数据库:drop database ...