C#弱引用

转载 2016年08月29日 14:31:59

转载自:http://www.cnblogs.com/mokey/archive/2011/11/24/2261605.html

一:什么是弱引用

      了解弱引用之前,先了解一下什么是强引用

  例如 : Object obj=new Object();     就是一个强引用,内存分配一份空间给用以存储Object数据,这块内存有一个首地址,也就是obj所保存的数据,内存分配的空间中不仅仅保存着Object对象信息,还保存着自己(Object本身)被引用的次数。

  当一个对象被强引用的形式创建的时候,本身被引用的次数已经为1.

  接着Object o=obj; 这句代码执行之后,obj指向的Object的存储空间已经被引用了2次,所以Object保存的被引用数值为2.

  总结:强引用最终导致的结果就是被引用的对象的被引用次数+1;

  相反的弱引用就是不会对被引用对象的被引用次数有任何影响。

二:弱引用有什么作用

  防止内存泄露。

  Object obj=new Object();

  当你在通过异步的形式访问网络上面的资源的时候,需要的时间可能会比较长,在数据返回之前,用户很可能转向了其他的页面,如果异步访问的对象(obj)对本地的一个对象(Object)是强引用的话,那么在这个异步访问对象(obj)被释放之前,也即在数据被回调之前,这个被引用的对象(Object)是不会被销毁的,这样一来,就导致内存一直被占用。

  WeakReference weakObj=new WeakReference(Object);

  此时就可以使用弱引用,弱引用对象(weakObj)发出异步请求,在回调之前,如果用户要转到其他的页面,这个被引用的对象(Object)是可以被释放的,这样子就不会出现内存一直被占用的现象。

三:怎样使用弱引用

  弱引用类: WeakReference //有两个重载的构造函数

  WeakReference WeakObj=new WeakReference(Object);//弱引用方式

  IsAlive属性是判断此弱引用对象所引用的对象是否还存在,存在:IsAlive=True;

     Target属性是设置该弱引用对象所引用的数据对象的值

     MSDN: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28SYSTEM.WEAKREFERENCE%29;k%28WEAKREFERENCE%29;k%28TargetFrameworkMoniker-%22SILVERLIGHT%2cVERSION%3dV4.0%22%29;k%28DevLang-CSHARP%29&rd=true


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

我们平常用的都是对象的强引用,如果有强引用存在,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));
            }
        }
}
相关

C#中的弱引用

一般情况下实例化一个类或结构时,只要有代码引用它,就会形成强引用。 例如: Student stu=new Student(); 对此,垃圾回收器就不能收集该对象。 一般而言是没有问题的,因为可...
  • u011470163
  • u011470163
  • 2014年03月04日 03:15
  • 1005

c#弱引用

强引用:            Object obj=new Object();     就是一个强引用,内存分配一份空间给用以存储Object数据,这块内存有一个首地址,也就是obj所保存的数据...
  • Let_G0
  • Let_G0
  • 2014年03月17日 19:57
  • 651

C#中的弱引用(WeakReference

转载自:http://www.cnblogs.com/bayonetxxx/archive/2009/06/02/1494728.html我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收...
  • leonwei
  • leonwei
  • 2016年09月08日 14:41
  • 2127

C# 强引用与弱引用的区别

我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用可...
  • m1654399928
  • m1654399928
  • 2013年07月04日 13:17
  • 2953

mono中的内存泄漏和WeakReference(弱引用)的使用

我们大家有时候在做 unity 项目的时候,游戏后期最常见的问题,应该就是内存泄漏了。 其实这里面有一些小细节,就可能在你不知不觉间导致内存泄漏的发生。 这里说说释放对象时容易发生的问题。...
  • WPAPA
  • WPAPA
  • 2016年05月26日 02:32
  • 3293

强引用、软引用、弱引用、虚引用(入门篇)

相信大伙一定听过强引用、弱引用、软引用、虚引用,到底什么是强引用、弱引用、软引用、虚引用????????????????         先从引用说起,在java中什么是引用?Person p = ...
  • cadi2011
  • cadi2011
  • 2016年11月16日 19:31
  • 743

C#垃圾回收和析构函数以及弱引用

在程序中,当我们每创建一个对象,就会在内存中开辟一个空间,用以存放这个对象。如果创建的对象多了,内存就会出现不够用的情况。这时我们就要把内存中不再使用的对象释放掉,避免内存的占用及程序的异常。这个过程...
  • u011416044
  • u011416044
  • 2013年10月03日 19:57
  • 1536

C# 使用弱引用释放静态资源

class Program     {         static void Main(string[] args)         {             TestClass.Defa...
  • The_Eyes
  • The_Eyes
  • 2017年05月25日 14:04
  • 412

弱引用总结及HashMap、List弱引用并Lru实现

Reference C++中有指针和Reference的概念,指针可以重新赋值,而Reference只能初始化时赋值。 然而,java中的Reference是可以重新赋值,并不是C++的Referen...
  • gongsunjinqian
  • gongsunjinqian
  • 2016年06月21日 17:27
  • 1061

Handler造成Activity泄漏,用弱引用真的有用么?

网上很多教程,解决Handler造成的内存泄漏问题,基本上是使用弱引用来解决的,但是使用弱引用真的有效么?直接写代码演示,以及分析。 下面分析过程分为4种,第一种是Handler声明成静态的并且弱引用...
  • u013356254
  • u013356254
  • 2016年09月07日 21:45
  • 5024
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#弱引用
举报原因:
原因补充:

(最多只允许输入30个字)