弱引用(System.WeakReference)

作者:追风剑情 发布于:2024-1-23 15:54 分类:C#

如果应用程序的代码可以访问一个正由该程序使用的对象,垃圾回收器就不能回收该对 象, 那么,就认为应用程序对该对象具有强引用。

弱引用允许应用程序访问对象,同时也允许垃圾回收器收集相应的对象。 如果不存在强 引用,则弱引用的有限期只限于收集对象前的一个不确定的时间段。 使用弱引用时,应 用程序仍可对该对象进行强引用,这样做可防止该对象被收集。 但始终存在这样的风 险:垃圾回收器在重新建立强引用之前先处理该对象。

占用大量内存,但通过垃圾回收功能回收以后很容易重新创建的对象特别适合使用弱引 用。

假设 Windows 窗体应用中的树状视图向用户显示层次结构复杂的选项。 如果基础数据量 很大,则用户使用应用程序中的其他部分时,在内存中保留该树会导致效率低下。

当用户切换到应用的其他部分时,可以使用 WeakReference 类创建对树的弱引用,并销 毁所有强引用。 当用户切换回该树时,应用程序会尝试获得对该树的强引用,如果成 功,就不必重新构造该树。

若要对某对象建立弱引用,请使用要跟踪的对象实例创建 WeakReference。 有关代码示 例,请参阅类库中的 WeakReference

短弱引用

垃圾回收功能回收对象后,短弱引用的目标(Target)会变为 null。 弱引用本身是托管对 象,与其他任何托管对象一样需要经过垃圾回收。 短弱引用是 WeakReference 的无 参数构造函数。

长弱引用

在对象的 Finalize 方法已调用后,长弱引用获得保留。 这样,便可以重新创建该对 象,但该对象仍保持不可预知的状态。 若要使用长引用,请在 WeakReference 构造 函数中指定 true。

如果对象类型不包含 Finalize 方法,应用的是短弱引用功能。弱引用只在目标被收 集前有效,运行终结器后可以随时收集目标。

若要建立强引用并重新使用对象,请将 WeakReference 的 Target 属性强制转换为对象类 型。 如果 Target 属性返回 null,表示对象已被收集;否则,可继续使用对象,因为应 用已重新获得对它的强引用。

使用弱引用的准则

  • 仅在必要时使用长弱引用,因为在终结后对象的状态不可预知。
  • 避免对小对象使用弱引用,因为指针本身可能和对象一样大,或者比对象还大。
  • 避免将弱引用作为内存管理问题的自动解决方案, 而应开发一个有效的缓存策略来处理 应用程序的对象。

示例

using System;

namespace ConsoleApp12
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //trackResurrection=true 表示长引用,当被引用的对象执行完终结器方法后仍然被跟踪
            //trackResurrection=false 表示短引用,当被引用的对象执行完终结器方法后结束跟踪
            WeakReference wr1 = new WeakReference(new TestObject(), true);
            WeakReference wr2 = new WeakReference(new TestObject(), true);
            Console.WriteLine("wr1.IsAlive="+wr1.IsAlive);
            Console.WriteLine("wr2.IsAlive="+wr2.IsAlive);
            Console.WriteLine("wr1.Target="+wr1.Target);
            Console.WriteLine("wr2.Target="+wr2.Target);
            //对第0代进行回收
            GC.Collect(0);
            //GC.WaitForPendingFinalizers();
            Console.WriteLine("wr1.IsAlive=" + wr1.IsAlive);
            Console.WriteLine("wr2.IsAlive=" + wr2.IsAlive);
            //Console.WriteLine("wr1.Target=" + wr1.Target);
            //Console.WriteLine("wr2.Target=" + wr2.Target);
            Console.ReadKey();
        }
    }

    public class TestObject
    {

    }
}  

运行测试
111111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号