无论是指类型的变量或是类类型的变量,其存储单元都是在栈中分配的,唯一不同的是类类型的变量实际上存储的是该类对象的指针,相当于vc6中的CType*,只是在.net平台的语言中将指针的概念屏蔽掉了。我们都知道栈的一大特点就是LIFO(后进先出),这恰好与作用域的特点相对应(在作用域的嵌套层次中,越深层次的作用域,其变量的优先级越高)。因此,对于楼主的问题,再出了“}”后,无论是值类型还是类类型的变量(对象指针)都会被立即释放(值得注意的是:该指针所指向的托管堆中的对象并未被释放,正等待GC的回收,这也许才是楼主想问的)。.NET中的栈空间是不归GC管理的,GC仅管理托管堆。
楼主的问题实际上提到了.NET与以前的VS语言的一个根本的不同,主要是由于GC存在。我想就我的理解简要说明一下:
1。GC只收集托管堆中的对象。
2。所有值类型的变量都在栈中分配,超出作用域后立即释放栈空间,这一点与VC6完全
一样。
3。区别类类型的变量和类的对象,这是两个不同的概念。类类型的变量实际上是该类对
象的指针变量。如C#中的定义CType myType;与VC6中的定义CType* myType;是完全一
样的,只是.net语言将*号隐藏了。与VC6相同,必须用new 关键字来构造一个对象,
如(C#):CType myType=new CType();其实这一条语句有两次内存分配,一次是为类类
型变量myType在栈中分配空间(指针类型所占的空间,对32位系统分配32位,64位
系统则分配64位,在同一个系统中,所有指针类型所占的内存空间都是一样的,而
不管该类型的指针所指向的是何种类型的对象),另一次是在托管堆(GC所管理的
堆)中构造一个CType类型的对象并将该对象的起始地址赋给变量myType。正因为如
此才造成了在同一个作用域中声明的类类型的变量和该类型的对象的生存期不一样。
4。类类型的变量的生存期是与其所定义的作用域相关的,也就是说出了“}”,它就立
刻烟消云散了。而对象的生存期却与传统意义上的作用域没有任何必然的联系,在作
用域嵌套层次中的任何一个层次中定义(准确地说应该是构造)的对象可以在程序生
存期的任何时刻被GC回收。
5。对象被回收必须满足两个条件:一是没有任何指向该对象的强引用(强弱引用这里
不详讲);二是GC回收操作被触发。这两个条件必须同时满足,对象才会被回收。
通常情况下,对象被回收是该对象被利用完以后很久之后的事情了。因此,.net中
没有析构函数,只有Finalize函数。dispose()函数的作用只是释放一些资源(比如
说打开的文件)而以,并不会析构对象。并且,dispose()的使用必须由程序员自己
控制。
6。无论如何,对象不能显式回收。即使你显式调用GC地回收功能,GC常常并不那么听
话的去执行回收操作。GC回收操作的触发是根据一定策略进行的。
7。应该说,GC回收是安全的,稳定的。但是其开销也很大,效率不够高,尤其是占用
内存很多,尽管微软采用了许多优化措施仍是如此。其开销也仅仅体现在GC进行垃
圾回收的那一霎那。
楼主的问题实际上提到了.NET与以前的VS语言的一个根本的不同,主要是由于GC存在。我想就我的理解简要说明一下:
1。GC只收集托管堆中的对象。
2。所有值类型的变量都在栈中分配,超出作用域后立即释放栈空间,这一点与VC6完全
一样。
3。区别类类型的变量和类的对象,这是两个不同的概念。类类型的变量实际上是该类对
象的指针变量。如C#中的定义CType myType;与VC6中的定义CType* myType;是完全一
样的,只是.net语言将*号隐藏了。与VC6相同,必须用new 关键字来构造一个对象,
如(C#):CType myType=new CType();其实这一条语句有两次内存分配,一次是为类类
型变量myType在栈中分配空间(指针类型所占的空间,对32位系统分配32位,64位
系统则分配64位,在同一个系统中,所有指针类型所占的内存空间都是一样的,而
不管该类型的指针所指向的是何种类型的对象),另一次是在托管堆(GC所管理的
堆)中构造一个CType类型的对象并将该对象的起始地址赋给变量myType。正因为如
此才造成了在同一个作用域中声明的类类型的变量和该类型的对象的生存期不一样。
4。类类型的变量的生存期是与其所定义的作用域相关的,也就是说出了“}”,它就立
刻烟消云散了。而对象的生存期却与传统意义上的作用域没有任何必然的联系,在作
用域嵌套层次中的任何一个层次中定义(准确地说应该是构造)的对象可以在程序生
存期的任何时刻被GC回收。
5。对象被回收必须满足两个条件:一是没有任何指向该对象的强引用(强弱引用这里
不详讲);二是GC回收操作被触发。这两个条件必须同时满足,对象才会被回收。
通常情况下,对象被回收是该对象被利用完以后很久之后的事情了。因此,.net中
没有析构函数,只有Finalize函数。dispose()函数的作用只是释放一些资源(比如
说打开的文件)而以,并不会析构对象。并且,dispose()的使用必须由程序员自己
控制。
6。无论如何,对象不能显式回收。即使你显式调用GC地回收功能,GC常常并不那么听
话的去执行回收操作。GC回收操作的触发是根据一定策略进行的。
7。应该说,GC回收是安全的,稳定的。但是其开销也很大,效率不够高,尤其是占用
内存很多,尽管微软采用了许多优化措施仍是如此。其开销也仅仅体现在GC进行垃
圾回收的那一霎那。