Why Java Sucks and C# Rocks(2):基础类型与面向对象
2010-05-04 00:00:00 来源:WEB开发网核心提示: 相信看了这几行代码您就能明白了,可以看出,Why Java Sucks and C# Rocks(2):基础类型与面向对象(5),在C#中,值类型和普通的类(也被称为引用类型)在使用上并没有任何区别,装箱和拆箱在.NET中是由运行时负责的,不需要特定的封装类,当然,既然被称为“值类型
相信看了这几行代码您就能明白了。可以看出,在C#中,值类型和普通的类(也被称为引用类型)在使用上并没有任何区别。
当然,既然被称为“值类型”,它自然和普通的引用类型有所区别。首先,在.NET中值类型在赋值时是“整体拷贝”而引用类型只是复制一个引用。更重要的是,值类型是分配在方法的调用栈上,而引用类型则是分配在托管堆上。这意味着前者在当前方法退出后会被自动释放,而后者则必须等待GC运行时将无用的对象消除。
换句话说,值类型不会对GC造成压力(除非进行了装箱),这点很重要。在某些场景中,例如在并行计算时,假如每个线程临时对象创建地过于频繁,则可能导致GC频率加大。而GC在启动时会暂停运行中的所有线程,因此并行计算最终的瓶颈可能就落在了单线程的GC上——此时您投入再多的CPU等运算资源也无济于事。解决这个问题一般有两种办法,首先是启用并行GC,则为每个CPU分配一个独立的托管堆。在执行时,对象会分配在当前CPU的托管堆上,每个托管堆也有一个线程负责GC操作,这样GC能力也会随着计算能力加大而提高,因此不会成为性能瓶颈。另一种,有时候也可能是更为合适的做法,便是将创建的临时对象设定为值类型,这样一切便是在调用栈上的读写操作,便不会对GC造成压力。
在.NET平台中,一旦将一个值类型的对象用作引用类型时(即转化为Object类型或接口),运行时便会对它进行“装箱”:此时运行时会在堆上创建一个对象,并将值类型的内容复制到对象内部。将一个装箱后的对象转化为值类型时,则会将托管堆上的对象内容复制到方法的调用栈上,这便是所谓的“拆箱”。装箱和拆箱在.NET中是由运行时负责的,不需要特定的封装类,支持任意值类型。
更多精彩
赞助商链接