-
不能在结构中定义析构函数。 只能对类使用析构函数。
-
一个类只能有一个析构函数。
-
无法继承或重载析构函数。
-
无法调用析构函数。 它们是被自动调用的。
-
析构函数既没有修饰符,也没有参数。
class Car { ~Car() // destructor { // cleanup statements... } }
该析构函数隐式地对对象的基类调用 Finalize。 这样,前面的析构函数代码被隐式地转换为以下代码:
protected override void Finalize() { try { // Cleanup statements... } finally { base.Finalize(); } }
这意味着对继承链中的所有实例递归地调用 Finalize 方法(从派生程度最大的到派生程度最小的)。
注意 不应使用空析构函数。 如果类包含析构函数,Finalize 队列中则会创建一个项。 调用析构函数时,将调用垃圾回收器来处理该队列。 如果析构函数为空,只会导致不必要的性能损失。
程序员无法控制何时调用析构函数,因为这是由垃圾回收器决定的。 垃圾回收器检查是否存在应用程序不再使用的对象。 如果垃圾回收器认为某个对象符合析构,则调用析构函数(如果有)并回收用来存储此对象的内存。 程序退出时也会调用析构函数。
可以通过调用 Collect 强制进行垃圾回收,但大多数情况下应避免这样做,因为这样会导致性能问题。
----------------------------------------- - http://topic.csdn.net/u/20100203/20/93821dcb-0ed5-4f47-9ac9-7581017d0d9b.html
- 以下摘自csdn论坛帖子
- 是的,楼主需要注意"析构函数"有“复活”一说。
-
当某种类型实现了 Finalize() 后,该对象将进行特殊的看待:此类型对象放置在GC的特殊位置——终结列表。
1、当进行第一次垃圾收集时,此类若没有其他引用,GC会对其进行回收,此时这些对象被认为是垃圾。进行GC.Collect 时,这些垃圾会被运送到另一个位置—— 终结可达队列。而终结可达队列,类似于全局或静态变量,会被当成一种GCRoot;
2、被放置在此队列(终结可达队列)中的对象,认为是可以访问的,因此可以认为这些对象原先被当成垃圾的对象【1中提到的对象】得到了“复活”,
3、当第一次 GC.Collect 执行后,GC会清空终结可达队列,此时【1】中的对象才是真正的垃圾。
4、等待下次执行 GC.Collect 时,【1】中对象才能完全被清理掉
其次,实现了 Finalize() 的对象,微软不保证其执行顺序,即:A,B 的Finalze的执行顺序是不保证的,因此不建议在A的 Finalize中访问B,或反推。因此,在实现Finalize时,微软推荐做法是同时实现 IDisposable 和 Finalize() ,即: IDisposable模式【直接取MSDN的实例】
非托管资源的释放与托管资源释放不一样,即使在将非托管对象置为null 或 null,其资源也不一定能释放。这个主要是非托管的资源的资源需手动释放【主要是历史问题,dotnet 之前没有GC的原因】。
其次,将托管对象(不包括静态变量,静态变量被GC当成root,这个可以用 windbg 之类的调试器看到)置为null 或 0,并不能“马上”释放其资源,什么时间执行析构,是GC决定的,主要是如下几个条件(可能不完全,可以查找相关内容):
.0代对象充满
.显示调用GC.Collect();
.内存不足
.CLR 程序域被卸载
.CLR 停止
本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/566366,如需转载请自行联系原作者