欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表

.net的对象生命周期原理

创建时间:2012年11月30日 20:18  阅读次数:(3494)
分享到:

对象生存期


本章已经重点讲述了对象和值是如何被分配和引用的。但对于程序员如何及什么时候,在整个运行程序的生存期内回收一个对象驻留的底层内存还没有进行阐述。这其实是CLR的一个特征,也是CLR托管执行模式的主要好处之一,即内存的回收不再是程序员考虑的事情。准确地说,CLR负责对所有内存的分配(和释放)。CLR用于管理内存的策略和机制是本章剩余部分的主题。

CLR知道在系统中的所有对象引用。正是根据这种全局的知识,运行时能够侦查到不再被引用的对象。运行时区别根引用和非根引用。根引用(root reference)往往是一个存活的局部变量或者一个类的静态字段。非根引用(nonroot reference)往往是一个对象的实例字段,根引用的存在足以使引用列象保持在内存中。没有根引用的对象潜在地不再使用。准确地说,
一个对象被保证驻留在内存中,只有通过遍历由根引用开始的对象层次结构时能否到达(reach)该对象。不能直接或间接由根引用到达的对象将受到自动内存回收的影响,也就是所谓的垃圾回收器(garbage collection,GC)。

图5.17显示了一个简单的对象层次结构,以及根引用与非根引用。注意根的集台是基于程序执行而变化的。在这个例子中,所显示的可到达(reachability)图反映的是ReadLine (加亮显示的)调用期间的情形。注意,词法的作用域并不重要。准确地说,CLR通过由JIT编译器创建的存活(Iiveness)信息,决定哪个局部变量是存活的,从而适合任何给定指令的指针值。这就是为什么在图5.17中temp2并不被认为是一个存活的根,有时候保持一个对象的引用,可以防止对象被垃圾回收。例如,在一个静态集合中保持一个命名对象的查找表,通常用来防止命名对象被垃圾回收。
uing System;
using System.Collections;

public class FancyObjects{
private string name;
private FancyObjects(string name){this.name=name;}

//命名对象的私有静态的缓存
Static IDictionary table=new Hashtable();

//公有的访问器函数
public Static FancyObject Get(string name){
Lock (typeof(FancyObjects)){
//检查缓存
FancyObject result={FancyObject|table[name];}

//如果缓存中没有,就创建它并加入缓存
If(result==null){
Result=new FancyObject(name);
Table[name]=result;
}
Return result;
}
}
}




这个类确保一个给定的命名对象同时至多有一千实例驻留在内存中,然而,由于CLR不能从该集台中删除由Hashtable对象持有的引用,因而这些对象不会被垃圾回收,原因就是Hashtable在其生存期中本身保证了这种可到达性。从理论上讲,由Hashtable表示的缓存本身只希望持有“建议性的( advisory)”引用,不足以保持目标对象的存活。这实际上是System.WeakReference类型的任务。

System.WeakRefererce类型在对象引用和目标对象之间添加了一个间接层,当垃圾回收器在查找根以决定哪个对象是可到达的时候,中间的WeakReference阻止垃圾回收器的进一步遍历。如果目标对象通过其他途径是不可达到的,那么,CLR将会回收该对象的内存。同样重要的是,CLR会设置WeakReference对象内的引用为nul1.以保证该对象被回收后不能再被访问。CLR通过WeakReference.Target属性使得这个内部引用有效,如果目标对象被回收了,该引用只是简单地返回null。
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 49+95=? 的结果(结果是:144)
结  果: