0

0

C# WeakReference是什么 - 创建对对象的弱引用,允许GC回收

幻夢星雲

幻夢星雲

发布时间:2026-01-04 11:45:27

|

697人浏览过

|

来源于php中文网

原创

WeakReference 是 C# 中不阻止 GC 回收对象的引用类型,适用于缓存、事件监听管理等场景;需通过 Target 或 TryGetTarget 检查有效性,推荐使用泛型 WeakReference。

c# weakreference是什么 - 创建对对象的弱引用,允许gc回收

WeakReference 是 C# 中一种特殊的引用类型,它不阻止垃圾回收器(GC)回收其所指向的对象。换句话说,只要没有强引用指向该对象,即使存在 WeakReference,GC 仍可在下一次回收周期中将其回收。

为什么需要 WeakReference?

常用于缓存、事件监听器管理、大对象临时持有等场景,避免因引用导致对象长期驻留内存,造成内存泄漏或资源浪费。

  • 比如缓存图像数据:用 WeakReference 持有,内存紧张时自动释放,下次需要时再重建
  • 比如 UI 控件订阅事件后忘记取消:用弱引用持有订阅者,避免控件已销毁但事件源仍强引用它

如何创建和使用 WeakReference

创建后需通过 Target 属性访问对象,并始终检查是否为 null(已被回收):

var obj = new byte[1024 * 1024]; // 1MB 对象
WeakReference weakRef = new WeakReference(obj);

obj = null; // 切断强引用 GC.Collect(); // 主动触发回收(仅调试用)

if (weakRef.Target is byte[] recovered) { Console.WriteLine("对象还在"); } else { Console.WriteLine("对象已被回收"); }

WeakReference — 泛型版本更安全

推荐使用泛型版 WeakReference,避免装箱/拆箱,类型安全,且提供 TryGetTarget(out T target) 方法,语义更清晰:

OpenJobs AI
OpenJobs AI

AI驱动的职位搜索推荐平台

下载
  • TryGetTarget 返回 bool 表示是否成功获取,同时输出目标对象
  • 无需类型转换,无运行时异常风险
  • 性能略优,尤其对值类型或频繁访问场景

注意点和常见误区

WeakReference 不是“延迟回收开关”,它不控制 GC 行为,只被动反映对象存活状态

  • GC 是否回收取决于当前内存压力、代龄、根引用等,WeakReference 无法预测或干预
  • 不要在多线程中直接多次访问 Target,应先用 TryGetTarget 获取一次并缓存结果
  • 不能用于跨 AppDomain 或序列化场景(.NET Core/.NET 5+ 已无 AppDomain)

基本上就这些。WeakReference 本身不复杂,但容易忽略“对象随时可能消失”这一本质,正确使用的关键是:始终检查有效性、避免重复解引用、优先选泛型版本。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

476

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

142

2025.12.24

C++类型转换方式
C++类型转换方式

本专题整合了C++类型转换相关内容,想了解更多相关内容,请阅读专题下面的文章。

292

2025.07.15

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

3

2026.01.08

java学习网站汇总
java学习网站汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 43.5万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号