程序在公共语言运行库(Common Language Runtime - CLR)运行时,内存从逻辑上分为2大块:栈、堆
线程栈(Stack)
、线程栈是一种先进后出的内存结构,由操作系统管理,存放值类型、引用类型的引用
、线程栈是基于线程的,一个线程会包含一个线程栈,当值类型在作用域结束后,会被编译器自动清理,效率很高
、线程栈空间较小,读取速度快
托管堆(Heap)
、托管堆是一块内存区域,由 CLR 管理,存储引用类型对象实例
、托管堆是进程初始化后,在进程地址空间上划分的内存区域,当堆满了之后,会由 GC(Garbage Collection)自动清理堆中的垃圾
、托管堆空间较大,读取速度慢
进程
、一个程序开始运行时,它就是一个进程
、进程由多个线程组成
线程
、线程是程序中独立的指令流
、不同的线程可以执行同样的函数
2种数据类型:值类型(Value types)、引用类型(Reference types)
值类型(Value types)
概念
、值类型需要一段内存,存储实际值,分配在声明的地方,作为局部变量时,存储在栈上;作为类字段时,跟随类存储在堆上
、变量声明时,就会分配内存
、派生自 System.ValueType
、给另一个变量赋值时,是创建一个新值
3个分类
、基本数据类型
、枚举(Enum)类型
、结构(Struct)类型
引用类型(Reference types)
概念
、引用类型需要两段内存,一段存储值的引用,分配在栈上;另一段存储实际值,分配在堆上
、变量声明时,只在栈上分配内存,存储引用,当实例化时,才会在堆上分配内存,存储对象实例
、派生自 System.Object
、给另一个变量赋值时,是创建一个新引用
5个分类
、类(Class)类型
、接口(Interface)类型
、委托(Delegate)类型
、数组类型
、字符串
3个类别:对象类型(Object)、动态类型(Dynamic)、字符串类型(String)
、Object:是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。可以被分配任何其他类型的值,分配之前,需要先进行类型转换
、Dynamic:可以存储任何类型的值在动态数据类型变量中,这些变量的类型检查是在运行时发生的
Object 与 Dynamic 相似,但是 Object 变量的类型检查是在编译时发生的,而 Dynamic 变量的类型检查是在运行时发生的
、String:允许给变量分配任何字符串值,可以通过两种形式进行分配:引号和 @引号
2种类型转换形式
、隐式转换:以安全方式进行的转换, 不会导致数据丢失
、显式转换:强制类型转换,需要强制转换运算符,会造成数据丢失
装箱:将值类型转换为引用类型,隐式转换
拆箱:将引用类型转换为值类型,显示转换
值类型 和 引用类型 区别
、存储:值类型存储实际值;引用类型存储引用
、内存:值类型分配在栈上;引用类型分配在堆上
、效率:值类型效率高;引用类型效率较低,需要地址转换
、回收:值类型用完自动回收;引用类型是交给 GC 处理
、赋值:值类型创建一个新值;引用类型是创建一个新引用
String 与 StringBuilder 区别
、String 继承自 Object 类;StringBuilder 继承自 AbstractStringBuilder
、String 是不可变类;StringBuilder 是可变类
、String 发生变化,会创建新对象,运行速度慢;StringBuilder 发生变化,是操作自身对象,运行速度慢