泉缘泉 发表于 2025-4-27 14:53:58

C#中的弱引用使用

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

​​与强引用的区别​​:
​​强引用​​:平凡对象引用(如 var obj = new MyClass())会阻止 GC 回收对象。
​​弱引用​​:不会阻止 GC 回收对象。当对象只有弱引用时,GC 可以随时回收它。
​​用途​​:
缓存大型数据(如图片、文件等),当内存不足时自动释放。
避免因恒久持有对象引用而导致内存泄漏。
监听变乱或观察对象生命周期,但不干预其回收。
使用:

1.基础使用:

代码:
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("对象没有被回收");
    }
} 效果:https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pLWJsb2cuY3NkbmltZy5jbi9kaXJlY3QvMDNkNWI3MjMyNzYyNGRjYWE1YTUwMjY2MzQ4ZjNjNjQucG5n
2.泛型使用:

代码:
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("对象没有被回收");
    }
} 效果:
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pLWJsb2cuY3NkbmltZy5jbi9kaXJlY3QvNTFkZjM2MmExOTJkNDMzZWFjN2U3NzMxMzUwNmQ3MTIucG5n
适用场景:

​​缓存​​:缓存大型对象,但允许 GC 在需要时回收它们。
变乱监听​​:避免变乱订阅导致的内存泄漏。
​​对象生命周期跟踪​​:观察对象是否存活,但不阻止其回收。
注:
性能​​:频繁检查弱引用是否存在可能影响性能。
​​不确定性​​:对象可能在任何时候被回收,需始终检查 IsAlive 或 TryGetTarget。
​​短期弱引用(Short Weak Reference)​​:默认举动,GC 回收后弱引用自动失效。
​​恒久弱引用(Long Weak Reference)​​:通过 WeakReference 构造函数指定 trackResurrection 为 true,可跟踪对象在终结后的状态(但极少使用)。
总结:

弱引用是 C# 中管理内存的一种高级机制,适用于需要机动控制对象生命周期的场景。正确使用它可以优化内存使用,但需审慎处理对象可能随时被回收的环境。
参考书籍或链接:
《C#高级编程》第2版


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C#中的弱引用使用