垃圾回收.docVIP

  1. 1、本文档共22页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
5.3 ?垃圾回收 本节将介绍以下内容: —? .NET垃圾回收机制 — 非托管资源的清理 5.3.1? 引言 .NET自动内存管理将开发人员从内存错误的泥潭中解放出来,这一切都归功于垃圾回收(GC,Garbage Collection)机制。 通过对对象创建全过程的讲述,我们理解了CLR执行对象内存分配的基本面貌。一个分配了内存空间和完成初始化的对象实例,就是一个CLR世界中的新生命体,其生命周期大概可以概括为:对象在系统中进行一定的操作和应用,到一定阶段它将不被系统中任何对象引用或操作,则表示该对象不会再被使用。因此,对象符合了可以销毁的条件,而CLR可能不会马上执行销毁操作,而是在适当的时间执行该对象的内存销毁。一旦被执行销毁,对象及其成员将不可在运行时使用,最后由垃圾收集器释放其内存资源,完成一个对象由生而灭的全过程。 由此可见,在.NET中自动内存管理是由垃圾回收器来执行的,GC自动完成对托管堆的全权管理,然而一股脑将所有事情交给GC,并非万全保障。基于性能与安全的考虑,很有必要对GC的工作机理、执行过程,以及对非托管资源的清理做一个讨论。 5.3.2? 垃圾回收 顾名思义,垃圾回收就是清理内存中的垃圾,因此了解垃圾回收机制就应从以下几个方面着手: l? 什么样的对象被GC认为是垃圾呢? l? 如何回收? l? 何时回收? l? 回收之后,又执行哪些操作? 清楚地回答上述几个问题,也就基本了解.NET的垃圾回收机制。下面本节就逐一揭开这几个问题的答案。 l? 什么样的对象被GC认为是垃圾呢? 简单地说,一个对象成为“垃圾”就表示该对象不被任何其他对象所引用。因此,GC必须采用一定的算法在托管堆中遍历所有对象,最终形成一个可达对象图,而不可达的对象将成为被释放的垃圾对象等待收集。 l? 如何回收? 每个应用程序有一组根(指针),根指向托管堆中的存储位置,由JIT编译器和CLR运行时维护根指针列表,主要包括全局变量、静态变量、局部变量和寄存器指针等。下面以一个简单的示例来说明,GC执行垃圾收集的具体过程。 class A { ??? private B objB; ??? public A(B o) ??? { ??????? objB = o; ??? } ??? ~A() ??? { ??????? Console.WriteLine(Destory A.); ??? } } class B { ??? private C objC; ??? public B(C o) ??? { ??????? objC = o; ??? } ??? ~B() ??? { ??????? Console.WriteLine(Destory B.); ??? } } class C { ??? ~C() ??? { ??????? Console.WriteLine(Destory C.); ??? } } public class Test_GCRun { ??? public static void Main() ??? { ??????? A a = new A(new B(new C())); ??????? //强制执行垃圾回收 ??????? GC.Collect(0); ??????? GC.WaitForPendingFinalizers(); ??? } } 在上述执行中,当创建类型A的对象a时,在托管堆中将新建类型B的实例(假设表示为objB)和类型C的实例(假设表示为objC),并且这几个对象之间保存着一定的联系。而局部变量a则相当于一个应用程序的根,假设其在托管堆中对应的实例表示为objA,则当前的引用关系可以表示为图5-6。 图5-6? 垃圾收集执行前的托管堆 垃圾收集器正是通过根指针列表来获得托管堆中的对象图,其中定义了应用程序根引用的托管堆中的对象,当垃圾收集器启动时,它假设所有对象都是可回收的垃圾,并开始遍历所有的根,将根引用的对象标记为可达对象添加到可达对象图中,在遍历过程中,如果根引用的对象还引用着其他对象,则该对象也被添加到可达对象图中,依次类推,垃圾收集器通过根列表的递归遍历,将能找到所有可达对象,并形成一个可达对象图。同时那些不可达对象则被认为是可回收对象,垃圾收集器接着运行垃圾收集进程来释放垃圾对象的内存空间。通常,将这种收集算法称为:标记和清除收集算法。 在上例中,a可以看出是应用程序的一个根,它在托管堆中对应的对象objA就是一个可达对象,而对象objA依次关联的objB、objC都是可达对象,被添加到可达对象图中。当Main方法运行结束时,a不再被引用,则其不再是一个根,此时通过GC.Collect强制启动垃圾收集器,a对应的objA,以及相关联的objB和objC将成为不可达对象,

文档评论(0)

精华文档888 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档