值类型与引用类型的性能差别

来源:互联网 发布:php允许ajax跨域 编辑:程序博客网 时间:2024/05/29 17:10

引用类型总是从托管堆上分配内存,C#的new操作符会返回对象的内存地址。使用引用类型是会引起下面的一些性能问题。

1、内存必须从托管堆上分配

2、堆上分配的每个对象都有一额外的成员,这些成员必须初始化

3、对象中的其他字节(为字段而设)总设为零

4、从托管堆上分配一个对象时,可能强制执行一次垃圾收集操作

除非以下所有的条件都满足,否则不应该讲一个类型声明为值类型

1、类型具有基元类型的行为。是一个十分简单的类型,其中没有成员会修改类型的任何实例字段。

2、类型不需要从任何其他类型继承

3、类型也不会派生出其他任何类型

4、类型的实例较小(约为16字节或者更小)

5、类型的实例较大(大于16字节)但不作为方法的实参传递,也不从方法返回

 

值类型和引用类型的一些不同

1、值类型对象有两种表示形式:未装箱形式和已装箱形式

2、值类型从system.ValueType派生的。system.ValueType从System.Object派生。该类型提供了与System.object定义相同的方法。然而,system.ValueType重写了Equals方法,能在两个对象的字段完全匹配的前提写返回true,除此之外,System.ValueType重写了GetHashCode方法生成哈希码的时候,这个重写方法所用的算法会将对象的实例字段中的值考虑在内。由于这个默认的实现存在性能问题,所以在定义自己的值类型时,应该重写Equals和GetHashCode方法,并提供它们的显示实现。

3、由于不能将一个值类型作为基类型来定义一个新的值类型或者一个新的引用类型,所以不应该在值类型中引入虚方法。所有的方法都不能是抽象的,而且所有的方法都隐士地为密封方法。

4、引用类型的变量包含的是堆上的一个对象的地址。默认的情况下,在创建一个引用类型的变量时,它被初始化为null,而值类型的所有成员都初始化为0。CLR提供了一个特殊的类型,能为值类型添加“可空性”标识。这个特性称为”可空“类型。

5、将一个值类型的变量付给另一个值类型的变量,会执行一次逐字段的复制,将引用类型的变量付给另一个引用类型的变量时,只会复制内存地址。

6、由于未装箱的值类型不在堆上分配,所以一旦定义了该类型的一个实例的方法不在处于活动状态,为他们分配的存储就会被释放。

原创粉丝点击