[.NET] WeakReference的使用

声明:本篇博客翻译自:http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.html

由于水平(技术水平+英语理解能力)有限/不足,肯定会有所疏漏/错误,请及时指正。

在日常开发中,通常会遇到一些大对象的处理。这些大对象通常在整个程序中多次使用。例如:大文件对象,大的字典类。通常情况下我们会使用下面的方式:

作为一个方法的内置本地变量;

作为一个类的字段存在;

这两种方式都不是很好。作为一个类的字段,类的实例将一直持有这个大对象,消耗很多内存;作为一个方法的本地变量使用,当方法执行完毕,这个大对象离开了作用域,但此时不一定会被GC直接回收。造成不必要的内存消耗。且每次调用该方法时,会重新创建新的大对象,增加程序的内存消耗。

如果创建对象很消耗资源,且我们想要避免多次创建同一个对象。可以使用类的字段方式。

通常情况下,当一个对象离开了作用域,或者被设置为null。我们将无法访问到它。.NET提供了一个WeakReference类,可以完美的解决这个问题。

WeakReference对象将保存一个对象的引用即使这个对象已经离开了作用域或者被设置为null了,通过WeakReference还可以访问到这个对象。除非被GC回收掉了,WeakReference对象此时无法访问到该对象。

WeakReference的使用非常简单,

MyHugeObject hugeObject = new MyHugeObject();
WeakReference w = new WeakReference(hugeObject);

通过WeakReference的Target属性可以获得关联的对象,

MyHugeObject = w.Target as MyHugeClass;

如果这个对象仍然存在,通过Target属性可以获得到。如果对象已经被GC回收了,Target得到的值为null

static void Func()
{
    MyHugeClass MyHugeObject;            
    if ( (w == null) || ( (MyHugeObject=w.Target as MyHugeClass) == null) )
    {
        MyHugeObject = new MyHugeClass();
        w = new WeakReference(MyHugeObject);
    }
    // work with MyHugeObject             
}

WeakReference提供给我们很大的好处:它将保持MyHugeObject的引用,并且确保可以在没有被GC回收的情况下重新得到该对象,且不用担心重新获得的对象是不完整的或者被损坏的。

PS:使用WeakReference并不能保证提高程序的性能,大多数情况下相比于使用本地局部变量而言性能会有所提高。但是不做任何担保。一些情况下还会出现更多的程序性能消耗,例如一个大对象关联了许多小对象,此时会将这些小对象也转成Weak Reference。此时会对GC内存回收有损耗。

参考链接:

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/weak-references

http://tipsandtricks.runicsoft.com/CSharp/WeakReferences.html

https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx

时间: 2024-08-25 06:37:29

[.NET] WeakReference的使用的相关文章

Android中的WeakReference 弱引用

WeakReference 弱引用 定义:弱引用,与强引用(我们常见的引用方式)相对:特点是:GC在回收时会忽略掉弱引用对象(忽略掉这种引用关系),即:就算弱引用指向了某个对象,但只要该对象没有被强引用指向,该对象也会被GC检查时回收掉. 强引用实例自然不会被GC回收! 如何引出弱引用?弱引用的实际用途是什么? 什么是内存泄漏?Java使用有向图机制,通过GC自动检查内存中的对象:如果GC发现一个或一组对象为不可达的状态,则将该对象从内存中回收.也就是说:一个对象不被任何引用所指向,则该对象会在

Java WeakReference的理解与使用

前言: 看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. 他没有期望有人能够完整解释清楚weak reference是什么, 怎么用, 只是期望有人能够提到这个concept和java的GC相关. 很可惜的是, 20多个拥有5年以上java开发经验的面试者中, 只有两人知道weak reference的存在, 而其中只有一人实际用到过他. 无疑, 在interviewer眼中, 对于weak referen

Java中关于WeakReference和WeakHashMap的理解

新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: 1 private static String test(){ 2 String a = new String("a"); 3 WeakReference<String> b = new WeakReference<String>(a); 4 WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, In

Threadlocal源码分析以及其中WeakReference作用分析

今天在看Spring 3.x企业应用开发实战,第九章 Spring的事务管理,9.2.2节ThreadLocal的接口方法时,书上有提到Threadlocal的简单实现,我就去看了下JDK1.8的Threadlocal的源码.发现实现方式与书中讲的并不相同,同时在网上搜索了一下,发现有比较多的人理解错了. 先看一下容易误导的解释:在ThreadLocal类中有一个Map对象,这个Map以每个Thread对象为键,保存了这个线程对应局部变量值,对应的实现方式如下: public class Sim

WeakReference &amp;&amp;reference quene &amp;&amp;GC

在了解WeakReference之前,先给出一段简单的代码: public class WeakReferenceTest {public static void main(String[] args) throws Exception {Object o = new Object();// 默认的构造函数,会使用ReferenceQueue.NULL 作为queueWeakReference<Object> wr = new WeakReference<Object>(o);Sy

java中虚引用PhantomReference与弱引用WeakReference(软引用SoftReference)的差别

之前的这篇博客介绍了java中4种引用的差别和使用场景,在最后的总结中提到: "软引用和弱引用差别不大,JVM都是先把SoftReference和WeakReference中的referent字段值设置成null,之后加入到引用队列:而虚引用则不同,如果某个堆中的对象,只有虚引用,那么JVM会将PhantomReference加入到引用队列中,JVM不会自动将referent字段值设置成null".这段总结写的比较仓促,也没有给出实际的例子加以佐证.本文主要是重申下这几种引用的差别,并

Java引用总结--StrongReference、SoftReference、WeakReference、PhantomReference

http://www.cnblogs.com/skywang12345/p/3154474.html 1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为:    强引用  >  软引用  >  弱引用  >  虚引用 ⑴强引用(StrongReference)    强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回

Java中引用类 strong reference .SoftReference 、 WeakReference 和 PhantomReference的区别

当在 Java 2 平台中首次引入 java.lang.ref 包,其中包含 SoftReference . WeakReference 和 PhantomReference 三个引用类,引用类的主要功能就是能够引用仍可以被垃圾收集器回收的对象.在引入引用类之前,我们只能使用强引用(strong reference).举例来说,下面一行代码显示的就是强引用 obj : Object obj = new Object(); obj 这个引用将引用堆中存储的一个对象.只要 obj 引用还存在,垃圾收

WeakReference(弱引用)

原地址:http://www.cnblogs.com/bayonetxxx/archive/2009/06/02/1494728.html 我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的.我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现.弱引用可以让您保持对对象的引用,同时允许GC在必要时释放对象,回收内存.对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望GC必