再谈一次值类型和引用类型

这篇文章大概会解决以下几个问题:

值类型是什么,引用类型是什么,

值类型和引用类型的区别

生命周期怎么说?怎么申请,怎么释放;

什么是装箱和拆箱。过程呢,怎么会触发装箱和拆箱呢

为什么值类型会更快?引用类型会慢一点

new操作符做了哪些东西

 

值类型是什么,引用类型是什么,

C#中的类型可以分为托管类型和非托管类型,这里我们只说托管类型。

托管类型可以简单分为两种,值类型和引用类型。

值类型的继承链为System.valueType,System.ValueType继承于System.Object。

而引用类型直接继承于System.Object。

C#中的基本类型里面int ,float ,double,demcial,char还有结构体等都是值类型。

引用类型,我们使用的class,接口,委托等。

值类型和引用类型的区别:

值类型在我们声明的时候就创建了,引用类型则需要使用new操作符。

 

内存分配位置:简单概括,引用类型分配在托管堆上,值类型在内存中的存放位置看他的具体环境,如果是局部变量,就是在线程栈上,如果是作为类的成员变量,则跟着类成员一起分配在托管堆上。

 

生命周期:值类型在作用域结束后立即回收,引用类型则是在没有对象引用之后在GC触发后回收,生命周期不确定。

 

复制:值类型复制的时候,是把数据复制成新的一份,内存中会存在两份值类型数据。引用类型则是声明了一个新的类型成员指针,同时指向旧的类型成员。两者引用的类型实例是同一份(浅拷贝);

 

什么是装箱和拆箱,以及何时触发装箱和拆箱?

值类型->引用类型,装箱

引用类型->值类型,拆箱

 

装箱和拆箱的时候做了哪些操作?

装箱:

1.系统在托管堆上分配内存,分配值类型各字段所需的内存量,类型对象指针及同步块索引

2.复制值类型实例至托管堆中。

3.返回对象的地址

 

拆箱

1.获取实例字段的地址

2.复制到栈的值类型中。

 

何时触发装箱?

1.显示装箱以外

2.在调用值类型中未实现的基类型中的函数,为了找到这个基类,需要使用类型对象指针,从而触发装箱。

 

为什么大家都说值类型会更快,引用类型慢?

值类型存储在线程栈上,使用的时候,需要做的只是移动栈指针,然后赋值;栈上的数据是连续的,CPU的Catch miss 会相应减少。

引用类型在使用的时候,会使用new函数来进行分配内存的操作。

首先,会在托管堆上分配内存,如果托管堆没有足够的空间,则会触发gc。

然后会对引用类型进行复制,最后返回引用类型的指针。

这样对比下来,值类型更快一点。

 

介绍一下new操作符做的事情

1.计算类型需要分配的字节数大小,分配内存。

2.初始化对象类型对象指针,同步块索引

3.调用类型的构造函数,传入new中的参数。

 

后记:

这篇文章的大部分内容是我看了《CLR Via C》#这本书得来的,推荐大家可以看看,如果有说的不对,望请各位指正。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值