当前位置 > 首页 > Asp.net

DOTNET中GC原理

2012-12-5 16:02:00来源:Asp.net

1. Stack和Heap
    每个线程对应一个stack,线程创建的时候CLR为其创建这个stack,stack主要作用是记录函数的执行情况。值类型变量(函数的参数、局部变量等非成员变量)都分配在stack中,引用类型的对象分配在heap中,在stack中保存heap对象的引用指针。GC只负责heap对象的释放,heap内存空间管理

Heap内存分配
   
    除去pinned object等影响,heap中的内存分配很简单,一个指针记录heap中分配的起始地址,根据对象大小连续的分配内存

Stack结构
    每个函数调用时,逻辑上在thread stack中会产生一个帧(stack frame),函数返回时对应的stack frame被释放掉
    用个简单的函数查看执行时CLR对栈的处理情况:
static void Main(string[] args)
{
    
int r = Sum(23456);
}
private static int Sum(int a, int b, int c, int d, int e)
{
    
return a + b + c + d + e;
}
    JIT编译后主要汇编代码如下(其他的情况下汇编代码可能有所差别,但用这个简单函数大致看下栈的管理已经足够):
;====函数Main====
push    4         ;第3个参数到最后一个参数压栈
push    5    
push    6    
mov    edx,3   ;第1、第2个参数分别放入ecx、edx寄存器
mov    ecx,2 
call    dword ptr ds:[00AD96B8h]  ;调用函数Sum,执行call的时候返回地址(即下面这条mov语句的地址)自动压栈了
mov    dword ptr [ebp-0Ch],eax   ;将函数返回值设置到局部变量r中(函数调用结束返回值在eax寄存器中)

;
====函数Sum====
push    ebp           ;保存原始ebp寄存器
mov    ebp,esp     ;将当前栈指针保存在ebp中,后面使用ebp对参数和局部变量寻址
sub    esp,8         ;分配两个局部变量
mov    dword ptr [ebp-4],ecx         ;第1个参数放入局部变量
mov