【C#】GC和析构函数(Finalize 方法)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【C#】GC和析构函数(Finalize 方法),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2314字,纯文字阅读大概需要4分钟。
内容图文

析构函数:
(来自百度百科)析构函数(destructor) 与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
C#中的析构函数定义与C++ 类似,~+函数名的方法:
生成的IL代码:
1 .class public auto ansi beforefieldinit Test.FinalizeClass 2 extends [mscorlib]System.Object 3 { 4 // Methods 5 .method family hidebysig virtual 6 instance void Finalize () cil managed 7 { 8 // Method begins at RVA 0x2070 9 // Code size 25 (0x19) 10 .maxstack 1 11 12 .try 13 { 14 IL_0000: nop 15 IL_0001: ldstr "FinalizeClass的析构函数" 16 IL_0006: call void [mscorlib]System.Console::WriteLine(string) 17 IL_000b: nop 18 IL_000c: nop 19 IL_000d: leave.s IL_0017 20 } // end .try 21 finally 22 { 23 IL_000f: ldarg.0 24 IL_0010: call instance void [mscorlib]System.Object::Finalize() 25 IL_0015: nop 26 IL_0016: endfinally 27 } // end handler 28 29 IL_0017: nop 30 IL_0018: ret 31 } // end of method FinalizeClass::Finalize 32 33 .method public hidebysig specialname rtspecialname 34 instance void .ctor () cil managed 35 { 36 // Method begins at RVA 0x20a8 37 // Code size 7 (0x7) 38 .maxstack 8 39 40 IL_0000: ldarg.0 41 IL_0001: call instance void [mscorlib]System.Object::.ctor() 42 IL_0006: ret 43 } // end of method FinalizeClass::.ctor 44 45 } // end of class Test.FinalizeClass
实际上生成了一个Finalize方法,内部调用了Base.Finalize()方法,也就是Object的Finalize 方法。
Finalize方法只能由GC调用,我们是不能调用的。下面说下GC调用Finalize的流程!
Finalization List(Queue)(终结列表)
我们new 一个对象,如果这个对象包含Finalize方法,开辟内存后,指向它的指针会被存放到终结列表中(Object对象除外)。
Freachable Queue (F-reachable终结可到达队列)
垃圾回收开始时,被判定为垃圾(不可达)的对象如果同时存在于Finalization List中,就会将该对象的指针从Finalization List移除,并存入Freachable Queue中。同时这些对象都变为可达(reachable),不会被GC回收,这样就意味着这些对象提升到另一代,这里假设为2代对象。
该队列中的对象都是可达的,并需要执行Finalize方法。执行Finalize方法是由一个高优先级的CLR线程进行的,执行完毕后,会将对象的指针从Freachable Queue中移除(当该队列为空时,此线程将睡眠,在不为空时被唤醒)。
当再次进行垃圾回收时,原Freachable Queue中的对象经过处理都变为不可达对象(2代),只有当2代内存不足时才会对2代对象进行垃圾回收,这些对象内存才会真正释放掉。因此含有Finalize方法的对象最少要经过两次垃圾回收才会被真正释放。
看图解:
对象2、3、5、6、10包含Finalize方法,2、5、7、9为不可达对象(GC的目标)。
进行GC时,由于2、5对象包含Finalize方法,因此被放入Freachable Queue中,变为可达对象并提升代,不进行垃圾回收。而对象7、9直接被回收。
如果原Freachable所在代进行GC,就会回收对象2、5的内存。
结论
1.含有Finalize方法的对象最少要经过两次垃圾回收才会被真正释放。
2.如非必要,不建议定义Finalize方法(用Dispose模式替代)。
原文:https://www.cnblogs.com/bruce1992/p/14613295.html
内容总结
以上是互联网集市为您收集整理的【C#】GC和析构函数(Finalize 方法)全部内容,希望文章能够帮你解决【C#】GC和析构函数(Finalize 方法)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。