C#中的弱引用使用

**弱引用(Weak Reference)**是一种特殊的引用类型,它允许你引用一个对象,但不会阻止该对象被垃圾回收器(GC)回收。弱引用通常用于需要缓存或跟踪对象,但又不希望因保留引用而导致内存泄漏的场景。弱引用对小对象没有意义,因为弱引用有自己的开销,这个开销可能比小对象更大。

核心概念​​

​​与强引用的区别​​ :
​​强引用​​ :普通对象引用(如 var obj = new MyClass())会阻止 GC 回收对象。
​​弱引用 ​​:不会阻止 GC 回收对象。当对象只有弱引用时,GC 可以随时回收它。
​​用途​​ :

缓存大型数据(如图片、文件等),当内存不足时自动释放。

避免因长期持有对象引用而导致内存泄漏。

监听事件或观察对象生命周期,但不干预其回收。

使用:

1.基础使用:

代码:

cs 复制代码
public class WeakReferenceTest : MonoBehaviour
{
    WeakReference weakRef;
    // Start is called before the first frame update
    void Start()
    {
        // 创建一个对象
        var myObject = new TestWeakReferenceObj();

        // 创建弱引用
        weakRef = new WeakReference(myObject);

        // 解除强引用,只保留弱引用
        myObject = null;

        // 通过弱引用访问对象
        if (weakRef.IsAlive)
        {
            var obj = weakRef.Target as TestWeakReferenceObj;
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }

    // Update is called once per frame
    void Update()
    {
        // 通过弱引用访问对象
        if (weakRef.IsAlive)
        {
            var obj = weakRef.Target as TestWeakReferenceObj;
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
}

class TestWeakReferenceObj { 
    public void DoSomething()
    {
        Debug.Log("对象没有被回收");
    }
}

结果:

2.泛型使用:

代码:

cs 复制代码
public class WeakReferenceTest : MonoBehaviour
{
    WeakReference<TestWeakReferenceObj> weakRefGeneric;
    // Start is called before the first frame update
    void Start()
    {
        weakRefGeneric = new WeakReference<TestWeakReferenceObj>(new TestWeakReferenceObj());

        if (weakRefGeneric.TryGetTarget(out TestWeakReferenceObj obj))
        {
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (weakRefGeneric.TryGetTarget(out TestWeakReferenceObj obj))
        {
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
}

class TestWeakReferenceObj { 
    public void DoSomething()
    {
        Debug.Log("对象没有被回收");
    }
}

结果:

适用场景:

​​缓存​ ​:缓存大型对象,但允许 GC 在需要时回收它们。
事件监听 ​​:避免事件订阅导致的内存泄漏。

​​对象生命周期跟踪​​:观察对象是否存活,但不阻止其回收。

注 :
性能 ​​:频繁检查弱引用是否存在可能影响性能。
​​不确定性 ​​:对象可能在任何时候被回收,需始终检查 IsAlive 或 TryGetTarget。
​​短期弱引用 (Short Weak Reference)​​:默认行为,GC 回收后弱引用自动失效。
​​长期弱引用(Long Weak Reference)​​:通过 WeakReference 构造函数指定 trackResurrection 为 true,可跟踪对象在终结后的状态(但极少使用)。

总结:

弱引用是 C# 中管理内存的一种高级机制,适用于需要灵活控制对象生命周期的场景。正确使用它可以优化内存使用,但需谨慎处理对象可能随时被回收的情况。

参考书籍或链接:

《C#高级编程》第2版

相关推荐
海宇大数据38 分钟前
零信任架构实战:基于海宇身份证OCR构建自动化跨境清关核验网关
人工智能·架构·c#·自动化
samble14 小时前
从零搭建灌装监控系统(十):生产追溯,条码触发自动记录
c#·wpf·mvvm·modbus·工业控制
czhc114007566319 小时前
退出防呆:用“总闸“收口所有退出入口,以及三个并发语法坑
开发语言·c#
淡海水21 小时前
02-01-原理篇-Mark-Sweep与变种算法
算法·unity·c#·游戏引擎·.net·gc
UIU1141 天前
同一个变量在两个 .c 文件里类型不一致,程序会怎样?
c++·学习·c#
波力海苔夹心脆6752 天前
C# 值类型与引用类型详解:存储位置、赋值机制、参数传递、相等比较、装箱拆箱与常见陷阱
开发语言·jvm·经验分享·笔记·c#·.net
估值探索者2 天前
【Python量化策略实战 #02】多因子合成mom和vol两因子打分合成
开发语言·c++·python·数据挖掘·c#
淡海水2 天前
01-04-认知篇-Unity内存全景
unity·c#·游戏引擎·.net·gc
淡海水2 天前
01-03-认知篇-C#内存模型深度解析
unity·c#·游戏引擎·.net·gc
lzhdim3 天前
C#不为人知的10个魔法特性:资深开发者也会震惊的底层奥秘
java·前端·javascript·算法·c#