net垃圾回收:原理浅析

net垃圾回收:原理浅析

ID:31772290

大小:60.76 KB

页数:9页

时间:2019-01-18

net垃圾回收:原理浅析_第1页
net垃圾回收:原理浅析_第2页
net垃圾回收:原理浅析_第3页
net垃圾回收:原理浅析_第4页
net垃圾回收:原理浅析_第5页
资源描述:

《net垃圾回收:原理浅析》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、•NET垃圾回收:原理浅析在开发.NET程序过程中,由于CLR中的垃圾回收(garbagecollection)机制会管理已分配的对象,所以程序员就可以不用关注对象什么时候释放内存空间了。但是,了解垃圾回收机制还是很有必要的,下面我们就看看.NET垃圾回收机制的相关内容。创建对象在C#中,我们可以通过new关键字创建一个引用类型的对象,比如下面一条语句。New关键字创建了一个Student类型的对象,这个新建的对象会被存放在托管堆中,而这个对象的引用会存放在调用栈中。(对于引用类型可以查看,C#中值类型和引用类型)Studentsl=newStudent();在C#中,当上面的Stu

2、dent对象被创建后,程序员就可以不用关心这个对象什么时候被销毁了,垃圾回收器将会在该对象不再需要时将其销毁。当一个进程初始化后,CLR就保留一块连续的内存空间,这段连续的内存空间就是我们说的托管堆。.NET垃圾回收器会管理并清理托管堆,它会在必要的时候压缩空的内存块来实现优化,为了辅助垃圾回收器的这一行为,托管堆保存着一个指针,这个指针准确地只是下一个对象将被分配的位置,被称为下一个对象的指针(NextObjPtr)0为了下面介绍垃圾回收机制,我们先详细看看new关键字都做了什么。new关键字当C#编译器遇到new关键字时,它会在方法的实现中加入一条CILnewobj命令,下面是通

3、过ILSpy看到的IL代码。IL_0001:newobjinstancevoidGCTest.Student::.ctor()其实,newobj指令就是告诉CLR去执行下列操作:计算新建对象所需要的内存总数检查托管堆,确保有足够的空间来存放新建的对象如果空间足够,调用类型的构造函数,将对象存放在NextObjPtr指向的内存地址如果空间不够,就会执行一次垃圾回收来清理托管堆(如果空间依然不够,就会报出OutofMemoryException)最后,移动NextObjPtr指向托管堆下一个可用地址,然后将对象引用返回给调用者按照上面的分析,当我们创建两个Student对象的时候,托管堆

4、就应该跟下图一致,NextObjPtr指向托管堆新的可用地址。托管堆的大小不是无限制的,如果我们一直使用new关键字来创建新的对象,托管堆就可能被耗尽,这时托管堆可以检测到NextObjPtr指向的空间超过了托管堆的地址空间,就需要做一次垃圾回收了,垃圾回收器会从托管堆中删除不可访问的对象应用程序的根垃圾回收器是如何确定一个对象不再需要,可以被安全的销毁?这里就要看一个应用程序根(applicationroot)的概念。根(root)就是一个存储位置其中保存着对托管堆上一个对象的引用,根可以属性下面任何一个类别:全局对象和静态对象的引用应用程序代码库中局部对象的引用传递进一个方法的对

5、象参数的引用等待被终结(finalize,后面介绍)对象的引用任何引用对象的CPU寄存器垃圾回收可以分为两个步骤:标记对象压缩托管堆下面结合应用程序的根的概念,我们来看看垃圾回收这两个步骤。标记对象在垃圾回收的过程中,垃圾回收器会认为托管堆中的所有对象都是垃圾,然后垃圾回收器会检查所有的根。为此,CLR会建立一个对象图,代表托管堆上所有可达对象。假设托管堆中有A-G七个对象,垃圾回收过程中垃圾回收器会检查所有的对象是否有活动根。这个例子的垃圾回收过程可以描述如下(灰色表示不可达对象):当发现有根引用了托管堆中的对象A时,垃圾回收器会对此对象A进行标记对一个根检测完毕后会接着检测下一个

6、根,执行步骤一种同样的标记过程,标记对象B,在标记B时,检测到对象B内又引用了另一个对象E,则也对E进行标记;由于E引用了G,同样的方式G也会被标记重复步骤二,检测Globales根,这次标记对象D代码中很有可能多个对象中引用了同一个对象E,垃圾回收器只要检测到对象E已经被标记过,则不再对对象E内所引用的对象进行检测,这样做有两个目的:一是提高性能,二是避免无限循环。所有的根对象都检查完之后,有标记的对象就是可达对象,未标记的对象就是不可达对象。压缩托管堆继续上面的例子,垃圾回收器将销毁所有未被标记的对象,释放这些垃圾对象所占的内存,再把可达对象移动到这里以压缩堆。注意,在移动可达对

7、象之后,所有引用这些对象的变量将无效,接着垃圾回收器要重新遍历应用程序的所有根来修改它们的引用。在这个过程中如果各个线程正在执行,很可能导致变量引用到无效的对象地址,所以整个进程的正在执行托管代码的线程是被挂起的。经过了垃圾回收之后,所有的非垃圾对象被移动到一起,并且所有的非垃圾对象的指针也被修改成移动后的内存地址,NextObjPtr指向最后一个非垃圾对象的后面。对象的代当CLR试图寻找不可达对象的时候,它需要遍历托管堆上的对象。随着程序的持续运行,托管

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。