我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用可以让您保持对对象的引用,同时允许GC在必要时释放对象,回收内存。对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望GC必要时回收时,可以考虑使用弱引用。弱引用使用起来很简单,看下面的代码:
Object obj = new Object();
WeakReference wref = new WeakReference( obj );
obj = null;

第一行代码新建了一个新的对象,这里叫它对象A,obj是对对象A的强引用。接着第二行代码新建了一个弱引用对象,参数就是对象A的强引用,第三行代码释放掉对对象A的强引用。这时如果GC进行回收,对象A就会被回收。
怎样在取得对象A的强引用呢?很简单,请看代码2:

Object obj2 = wref.Target;
if( obj2 != null )
{
   // 做你想做的事吧。
}
else
{
// 对象已经被回收,如果要用必须新建一个。
}

只要显示的将弱引用的Target属性附值就会得到弱引用所代表对象的一个强引用。不过在使用对象之前要对其可用性进行检查,因为它可能已经被回收了。如 果你得到的是null(VB.NET下为Nothing),表明对象已经被回收,不能再用了,需要重新分配一个。如果不是null,就可以放心大胆的用 了。
接下来让我们看WeakReference的另外一个版本,请看代码3:
// public WeakReference(
//   object target,
//   bool trackResurrection
//);

Object obj1 = new Object();

Object obj2 = new Object();

WeakReference wref1 = new WeakReference( obj1, false );

WeakReference wref2 = new WeakReference( obj2, true );

WeakReference的另外一个版本有两个参数,第一个参数和我们前面用的版本的一样。第二个参数让我们看一下他的原型,bool trackResurrection,跟踪复活,是个bool型,就是是否跟踪复活。前面的文章中我提到过需要Finalize的对象在最终释放前会有一 次复活,我们大概可以猜到第二个参数表示的意思了。如果我们第二个参数给false,这个弱引用就是一个short weak reference(短弱引用),当GC回收时,发现根中没有这个对象的引用了,就认为这个对象无用,这时短弱引用对这个对象的跟踪到此为止,弱引用的 Target被设置为null。前面的一个参数的构造函数版本新建的弱引用为短弱引用。如果第二个参数给true,这个弱引用就是一个long weak reference(长弱引用)。在对象的Finalize方法没有被执行以前,Target都可用。不过这是对象的某些成员变量也许已经被回收,所以使 用起来要想当小心。
现在让我们看看WeakReference是如何实现的。很显然WeakReference不能直接的引用目标对象,WeakReference的 Target属性的get/set是两个函数,从某处查到目标对象的引用返回,而不是我们最常用写的那样直接返回或者设置一个私有变量。GC维护了两个列 表来跟踪两种弱引用的目标对象,在一个 WeakReference对象创建时,它在相应的列表中找到一个位置,将目标对象的引用放入,很显然,这两个列表不是根的一部分。在GC进行内存回收的 时候,如果要回收某一个对象,会检查弱引用的列表,如果保存着这个对象的引用,则将其设为null。 
public class AspPage : Page
{
private static ArrayList __ENCList = new ArrayList();

[DebuggerNonUserCode]
        public AspPage()
        {
            base.Load += new EventHandler(this.Page_Load);
            ArrayList list = __ENCList;
            lock (list)
            {
                __ENCList.Add(new WeakReference(this));
            }
        }

}

转载自:http://www.cnblogs.com/bayonetxxx/archive/2009/06/02/1494728.html

最新文章

  1. Linux 14.04lts 环境下搭建交叉编译环境arm-linux-gcc-4.5.1
  2. UITableViewCell 多选和全选(checkBoxCell)
  3. Hive介绍、安装(转)
  4. BizTalk开发系列(十五) Schema设计之Qualified 与Unqualified
  5. 我的android学习经历32
  6. 参加 TiD 2015 是怎样一番体验?
  7. BAT批处理(二)
  8. ectouch第七讲 之ECshop模板机制整理
  9. java编程之:org.apache.commons.lang3.text.StrTokenizer
  10. Node.js 入门(2)
  11. Spring4.0学习笔记(5) —— 管理bean的生命周期
  12. oracle 查询重复数据
  13. C# 对象池的实现
  14. A项目轶事之加入项目2个月
  15. scrapy基础 之 爬虫入门:先用urllib2来跑几个爬虫
  16. MySQL报错解决方案:2013-Lost connection to MySQL server
  17. Netty 学习笔记(1)通信原理
  18. 云主机IO性能测试
  19. Underscore.js(JavaScript对象操作方法)
  20. 【转】netty源码分析之LengthFieldBasedFrameDecoder

热门文章

  1. The Road to learn React书籍学习笔记(第四章)
  2. js 邮箱和手机号码验证
  3. 【APUE】Chapter15 Interprocess Communication
  4. JMeter接口响应数据出现乱码的三种解决方法
  5. 学习人工智能的第六个月[深度学习[Deep Learning,DL]]
  6. ipfs补充命令
  7. SQL 视图 局部变量 全局变量 条件语句 事务 触发器
  8. Maven中mirrors和repository的关系
  9. Delphi 之 编辑框控件(TEdit)
  10. 在程序内部跳转到下一个页面 和 向另一个servlet发起跳转