C#中堆和栈的区别
- 堆与栈的概念及不同点:
- 在内存中栈主要负责处理线程中的命令,并且是以栈Stack的形式读取与执行的;
- 堆主要是存储方法体以及数据,类似于床上散落的衣服,可供随机读取。
- 堆和栈上的垃圾回收:
- 栈有自我维护特性,执行完语句马上释放不会造成资源泄漏。
- 堆则需GC回收,并且符合GC回收的规则,很多堆上的内容在程序退出前都没有被回收,很可能是无意中某处还保留着内容的引用导致,这将严重影响性能。
内存的分配:
- 堆栈(stack)是一种后进先出的数据结构,在内存中,变量会被分配在堆栈上来进行操作。
- 堆(heap)是用于为类型实例(对象)分配空间的内存区域,在堆上创建一个对象,会将对象的地址传给堆栈上的变量(反过来叫变量指向此对象,或者变量引用此对象)。
相关阅读
C#中值类型和引用类型的区别
- C# 中的类型一共分为两类,一类是值类型(
Value Type
),一类是引用类型(Reference Type
)。 - 值类型与引用类型不同点:引用类型永远存在于托管堆上,值类型在哪取决于声明的位置。
- 值类型包括 结构和枚举,引用类型包括类、接口、委托 等。还有一种特殊的值类型,称为简单类型(Simple Type),比如 byte,int等,这些简单类型实际上是FCL类库类型的别名,比如声明一个int类型,实际上是声明一个System.Int32结构类型。因此,在Int32类型中定义的操作,都可以应用在int类型上,比如 “123.Equals(2)”。
- 所有的 值类型 都隐式地继承自
System.ValueType
类型(注意System.ValueType
本身是一个类类型) System.ValueType
和所有的引用类型都继承自System.Object
基类。- 你不能显示地让结构继承一个类,因为C#不支持多重继承,而结构已经隐式继承自
ValueType
。 - 值类型继承自
System.ValueType
; 引用类型继承自System.Object
- 值类型与引用类型在改变内容时处理的方式不同:值类型执行内容拷贝,引用类型始终更改的是所引用的内容,这将导致两者行为上的不一致。
- 值类型当参数时,复制拷贝为一个栈上的新对象,使用后回收。
- 值类型当参数时,会发生拷贝现象,所以对一些“很大”的结构体类型会产生很严重的效率问题,可尝试用
ref
关键字将结构体包装成引用类型进行传递,节省空间及时间。 - 引用类型传递的是引用地址,即多个事物指向同一个内存块,如果更改内存中的值将同时反馈到所有其引用的对象上。
ref
关键字传递的是引用类型的指针,而非引用类型地址。(当声明参数带有ref
关键字时,引用类型传递的是引用类型的指针,相反如果没有ref关键字,参数传递的是新的指向引用内容的指针(引用))- 相关阅读: C# 类型基础
C#中有指针吗?
C#为了类型安全,默认并不支持指针。但是也并不是说C#不支持指针,我们可以使用unsafe关键词,开启不安全代码(unsafe code)开发模式。在不安全模式下,我们可以直接操作内存,这样就可以使用指针了。在不安全模式下,CLR并不检测unsafe代码的安全,而是直接执行代码。unsafe代码的安全需要开发人员自行检测。
相关阅读 :C# 不安全代码
C#中结构体和类的区别是什么
C#中装箱和拆箱的区别
装箱是将值类型转换为
object
类型或由此值类型实现的任何接口类型的过程。对值类型进行装箱时,会将该值包装到
System.Object
内部,再将后者存储在托管堆上。取消装箱将从对象中提取值类型。
装箱是隐式的(也可以进行显式装箱);取消装箱是显式的。
//隐式装箱 int i = 123; object o = i; //显式装箱 int i = 123; object o = (object)i; // explicit boxing //显示取消装箱 int i = 123; // a v