• 也说.NET中的弱引用


     一般认为在应用程序执行期间,对象在任意时刻要么是活动的,即表示应用程序有指向对象的引用;要么对象是非活动的。当应用程序释放了指向对象的最后一个引用后,对象就从活动状态变为不活动状态了。

     但是事实上,对象在“活动状态”和“非活动状态”之间还有一个第三种状态。如果对象处在这种状态下,应用程序可以访问对象,而CLR的垃圾收集器(GC)也可以随时释放对象。哎!这好象是很矛盾的啊?应用程序可以访问对象就说明还有引用指向对象啊,怎么可能会被GC随时释放啊?为了解决这个矛盾,就引入了这篇随笔所要说的弱引用(Weak Reference)了。当对象是以弱引用的方式引用的,那么对象就处于我们前面所说的第三种状态了,也就是说对象即可以被应用程序引用,也可以随时被GC释放。

     那么.NET为什么要提供弱引用这个功能,这既增加了对象状态的复杂性,也加大了我们学习的难度,好象很不合算吗?其实弱引用还是很有用的,一般认为当满足下列条件时,我们就应该考虑使用弱引用:

    1. 对象稍后可能被使用,但不是很确定。(如果确定要使用,就应该用强引用)
    2. 如果需要,对象可以重新被构造出来(比如数据库构造)。
    3. 对象占相对比较大的内存(一般大于几KB以上)

      好象上面所列的条件很理论很晦涩啊!其实在日常实践中,可以用一句话来概括:弱引用一般用来完成对象的缓存,以提高应用程序的性能。

    既然使用弱引用有好处,并且我们又知道了应该在何时使用它,那到底应该如何使用引应用呢?说了这么多,怎么还不说弱引用的使用方法啊?别急,让我们来看一个例子:

     protected void Page_Load(object sender, EventArgs e)
            
    {
                
    // 声明一个强类型引用对象
                object obj = new object();

                // 注意:这里声明了一个弱引用对象

                System.WeakReference wobj = new WeakReference(

                obj 
    = null; // 删除强类型引用

                obj 
    = wobj; 

                
    // 下面的两个Response.Write语句都有可能被执行,
                
    // 不过一般else下的Response.Write语句执行的机率高些,
                
    // 因为GC只有在CLR监测到内存不足时,才进行垃圾收集
                if (null == obj)
                
    {
                    Response.Write(
    "弱类型引用对象被清除");
                }

                
    else
                
    {
                    Response.Write(
    "弱类型引用对象可以使用");
                }
          
            }
    怎么样,看了上面的例子,是不是发现弱引用的使用是很简单的一件事啊?其实WeakReference类提供了两个构造函数:
    WeakReference(object target);
    WeakReference(object target, bool trackResurrection);。
    如果我们像上面的例子中那样使用第一个构造函数,那traceResurrection将会被置为默认值false。同样我们可以利用第二个构造函数将traceResurrection置为true。那这个参数究竟有什么用呢?其实当traceResurrection为true时,应用程序就可以在对象的Finalize()方法被调用后,但对象的内存还没有真正发生改变(即GC垃圾收集操作的堆碎片清理还没有清理到对象所使用的内存区域)的这段时间里继续访问对象。对于这种情况我们一般称之为“长弱引用”。对应的,当traceResurrection被置为false,我们称之为“短弱引用”。

     最后说一句,虽然有时候长弱引用可以给我们带来一定的方便性,当我们最好避免使用它,因为长弱引用的维护十分困难。

  • 相关阅读:
    博客园首页CSS模板
    style、currentStyle、getComputedStyle的区别和用法
    createDocumentFragment创建文档碎片节点
    setTimeout里如果有$(this),$(this)指的是谁?
    让ie也兼容placeholder
    eval()函数可以把一个字符串当作一个JavaScript表达式一样去执行它
    遮罩层特效(根据鼠标进入离开方向出现)
    jquery之attr和prop区别
    js封装类简单举例
    自动换行 word-break:break-all和word-wrap:break-word
  • 原文地址:https://www.cnblogs.com/zhangronghua/p/1120479.html
Copyright © 2020-2023  润新知