Microsoft.Net框架程序设计学习笔记(36):弱引用

  假设有这样一些数据结构,它们很容易创建但却需要大量的内存和时间。如:我们需要知道用户硬盘中所有目录和文件,我们可以很容易构造一个树来反映这些信息,当应用程序运行时,它可以引用内存中的树,而不必再访问用户的硬盘。这样显然会极大提高应用程序的性能。

  但问题在于这个树可能会非常庞大,需要许多内存。如果用户转而访问应用程序的其余部分,那么这个树可能变得不再必要,却浪费着许多内存。我们可能会放弃这个树的根对象的引用,但如果用户又切换回应用程序的第一部分,那我们又需要重新构造该树。使用弱引用,我们可以方便、高效的处理这种情况。

  弱引用对象是这样一种对象,如果我们放弃该对象的强引用,将其转至弱引用时,它允许垃圾收集器收集该对象。但如果垃圾收集器尚未来得及收集该对象,我们又可从弱引用中重新获取该对象,此时弱引用又转换成了强引用对象。是不是很绕口?看看下面的代码吧:

  
    
using System;
using System.Collections.Generic;
using System.Text;

namespace DisposeTest
{
class Program
{
static void Main( string [] args)
{
// 创建一个新对象的强引用
object o = new object ();

// 创建一个弱引用对象,该对象指向o,负责追踪对象o的生存期
WeakReference wr = new WeakReference(o);

// 移除对象的强引用
o = null ;
// 重新获取弱引用指向的对象
o = wr.Target;
// 输出对象o的状态
Output(o);

o
= null ;
// 手动执行垃圾收集
GC.Collect();
// 重新获取弱引用指向的对象
o = wr.Target;
// 输出对象o的状态
Output(o);

Console.ReadKey();
}

// 输出对象o的状态
private static void Output( object o)
{
if (o == null )
{
// o指向null,表明出现过垃圾收集,弱引用指向的对象内存已被回收
Console.WriteLine( " 我已经被当成垃圾处理了! " );
}
else
{
// o不指向null,表明未出现过垃圾收集,该弱引用对象可重新使用
Console.WriteLine( " 我还活着耶! " );
}
}
}
}

  这段代码的输出为:

  我还活着耶!
  我已经被当成垃圾处理了!

  代码很简单,看懂了吧!

  至于弱引用的内部机理,简单的说就是托管堆中有两个弱引用表:短弱引用表和长弱引用表。(短弱引用、长弱引用的含义就不再介绍了,大家查相关资料,或查看本书,建议避免使用长弱引用)创建一个弱引用对象时,会在这两个弱引用表中选择一个,并在其中记录弱引用所指对象地址。如果弱引用对象的内存被回收了,弱引用表中该对象所记录的对象地址亦被置为null。这样程序再获取该弱引用时,就只得到一个为null的地址了。咱们也就知道该对象已经被收集了,只有重建该对象了。否则对象仍活着,可以继续使用。

你可能感兴趣的:(Microsoft)