初学C#: C#中的各种"对象"(变量)有作用域吗?某个对象在 { 中定义,出了 } 就会被回收吗? 应该是回收无效的引用吧,你说的int是值类型的,是在堆栈中保存的,当然是出了“}”就没了, 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在C#中,变量自动回收效率不高,而且不稳定,不像C++,程序员靠自己定义是否回收,安全性,效率又高,这一点,C#是有利有弊的! 你也可以用using,using完后,系统自动dispose() 无论是指类型的变量或是类类型的变量,其存储单元都是在栈中分配的,唯一不同的是类类型的变量实际上存储的是该类对象的指针,相当于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的理解说出来与大家交流交流,可能有很多理解错误,恳请高手不吝赐教。可直接与我联系交流。 email:[email protected] 谢谢kft2001(乘风而来)说了这么多,也谢谢cqnimin() ,我以前看过using这个用法,不过一时忘了,这才想起来, C#编写一个USB接口通信的程序 查询多个表(字段差不多相同)合并结果,并按一个时间字段排序 100分求个代码???? 调用Attribute的方法 WPF的UI中嵌入了一个MFC的CView,如何判断当前鼠标是否在CView上? datagridview 编辑新行的问题 C# 调用C++ dll 求解 。。。急。。。。。 如何跟踪客户端的连接状态 怎么样将DataGrid导出成一个Excel文件? 求教:一个搞不懂的C++声明 两个问题,打开网页和发送邮件? 分别出来控件和他的容器的透明属性.
楼主的问题实际上提到了.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的理解说出来与大家交流交流,可能有很多理解错误,恳请高手不吝赐教。可直接与我联系交流。
email:[email protected]