.NET 内存模型-----堆栈与托管堆
堆栈(STACK):跟踪正在执行的代码(调用的函数)
托管堆(HEAP):跟踪我们的对象object/data.
STACK和HEAP的形象化比喻STACK是先进后出的,只能使用TOP.而HEAP是可以随取随放的。
STACK是自我维护的,自己负责自己的内存管理(memory management),TOP层的数据不再用的时候就被扔了。而HEAP和GC(紧密相关)。
STACK和HEAP主要负责四种类型的数据:
值类型(VALUE);引用类型(REFERENCE);指针(POINTERS);指令(INSTRUCTIONS)。
C#中的值类型:
bool
byte
char
decimal
double
enum
float
int
long
sbyte
short
struct
uint
ulong
ushort
C#中的引用类型(继承自SYSTEM.OBJECT):
class
interface
delegate
object
string
指针:
指针(或者引用)和引用类型完全是两个不同的概念。我们不会直接用到它,因为它被CLR自己维护的。一个指针是一块指向另一块内存空间的内存空间。指针就像我们放置在STACK或者HEAP中的数据一样,只不过它的值是内存地址罢了。
指针的形象化解释值类型通常保存在STACK中,作为一个线程维护状态的参数空间/一个线程运行时有自己的虚拟内存(method call涉及body里的变量)
下面是两个例子:
1.值类型
public int AddFive(intpValue)
{int result;
result = pValue + 5;
return result;
}
1.过程开始 2.result入栈 3. 这个method call结束4.结束,释放内存空间
2.引用类型
public class MyInt{
public int MyValue;
}
接下来执行的函数:
public MyInt AddFive(int pValue)
{MyInt result =new MyInt();
result.MyValue = pValue + 5;
return result;}
1.进程开始 2.result涉及引用类型MyInt,指针进栈 3.函数结束,栈释放内存空间 4.栈空了,堆的内存空间未释放这个时候GC垃圾回收开始发挥作用,当内存空间不够时,GC停止所有正在运行的线程THREAD,然后检查HEAP中哪些objects不再被用了,回收它们。
当我们处理引用类型的时候,我们处理的是对应类型的指针,而不是它自己;当我们处理值类型的时候,我们处理的就是它自己。
CTS(通用)的值类型可分为简单类型、枚举类型和结构类型,而引用类型则分为类类型、数组类型、接口类型和委托类型。最后,值类型是密封的,不能派生其他类型,而且值类型必须继承自System.Value,相反,引用类型可以继承除System.Value以外的任何非封装类型。