C#中的弱引用(WeakReference)
我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用可以让您保持对对象的引用,同时允许GC在必要时释放对象,回收内存。对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望GC必要时回收时,可以考虑使用弱引用。弱引用使用起来很简单,看下面的代码:
Object obj = new Object();
WeakReference wref = new WeakReference( obj );
obj = null;
第一行代码新建了一个新的对象,这里叫它对象A,obj是对对象A的强引用。接着第二行代码新建了一个弱引用对象,参数就是对象A的强引用,第三行代码释放掉对对象A的强引用。这时如果GC进行回收,对象A就会被回收。
怎样在取得对象A的强引用呢?很简单,请看代码2:
Object obj2 = wref.Target;
if( obj2 != null )
{
// 做你想做的事吧。
}
else
{
// 对象已经被回收,如果要用必须新建一个。
}
只要显示的将弱引用的Target属性附值就会得到弱引用所代表对象的一个强引用。不过在使用对象之前要对其可用性进行检查,因为它可能已经被回收了。如 果你得到的是null(VB.NET下为Nothing),表明对象已经被回收,不能再用了,需要重新分配一个。如果不是null,就可以放心大胆的用 了。
接下来让我们看WeakReference的另外一个版本,请看代码3:
// public WeakReference(
// object target,
// bool trackResurrection
//);
Object obj1 = new Object();
Object obj2 = new Object();
WeakReference wref1 = new WeakReference( obj1, false );
WeakReference wref2 = new WeakReference( obj2, true );
WeakReference的另外一个版本有两个参数,第一个参数和我们前面用的版本的一样。第二个参数让我们看一下他的原型,bool trackResurrection,跟踪复活,是个bool型,就是是否跟踪复活。前面的文章中我提到过需要Finalize的对象在最终释放前会有一 次复活,我们大概可以猜到第二个参数表示的意思了。如果我们第二个参数给false,这个弱引用就是一个short weak reference(短弱引用),当GC回收时,发现根中没有这个对象的引用了,就认为这个对象无用,这时短弱引用对这个对象的跟踪到此为止,弱引用的 Target被设置为null。前面的一个参数的构造函数版本新建的弱引用为短弱引用。如果第二个参数给true,这个弱引用就是一个long weak reference(长弱引用)。在对象的Finalize方法没有被执行以前,Target都可用。不过这是对象的某些成员变量也许已经被回收,所以使 用起来要想当小心。
现在让我们看看WeakReference是如何实现的。很显然WeakReference不能直接的引用目标对象,WeakReference的 Target属性的get/set是两个函数,从某处查到目标对象的引用返回,而不是我们最常用写的那样直接返回或者设置一个私有变量。GC维护了两个列 表来跟踪两种弱引用的目标对象,在一个 WeakReference对象创建时,它在相应的列表中找到一个位置,将目标对象的引用放入,很显然,这两个列表不是根的一部分。在GC进行内存回收的 时候,如果要回收某一个对象,会检查弱引用的列表,如果保存着这个对象的引用,则将其设为null。
public class AspPage : Page
{
private static ArrayList __ENCList = new ArrayList();
[DebuggerNonUserCode]
public AspPage()
{
base.Load += new EventHandler(this.Page_Load);
ArrayList list = __ENCList;
lock (list)
{
__ENCList.Add(new WeakReference(this));
}
}
}
转载自:http://www.cnblogs.com/bayonetxxx/archive/2009/06/02/1494728.html
C#中的弱引用(WeakReference)的更多相关文章
- C# 中的弱引用 WeakReference
C#中的弱引用(WeakReference) 我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的.我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET ...
- java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)
之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
因为之前项目同事使用了图片三级缓存,今天整理项目的时候发现同事还是使用了软引用(SoftRefrerence)和弱引用(WeakReference),来管理在内存中的缓存.看到这个我就感觉不对了.脑海 ...
- WeakHashMap<K,V> 中的弱引用
相信很多人对WeakHashMap并没有完全理解. WeakHashMap 持有的弱引用的 Key. 1. 弱引用的概念: 弱引用是用来描述非必需对象的,被弱引用关联的对象只能生存到下一次垃圾收集发生 ...
- 简单说说.Net中的弱引用
弱引用是什么? 要搞清楚什么是弱引用,我们需要先知道强引用是什么.强引用并不是什么深奥的概念,其实我们平时所使用的.Net引用就是强引用.例如: Cat kitty = new Cat(); 变量ki ...
- .NET中的弱引用
弱引用是什么? 要搞清楚什么是弱引用,我们需要先知道强引用是什么.强引用并不是什么深奥的概念,其实我们平时所使用的.Net引用就是强引用.例如: Cat cat = new Cat(); 变量cat就 ...
- 关于C#中的弱引用
本文前部分来自:http://www.cnblogs.com/mokey/archive/2011/11/24/2261605.html 分割线后为作者补充部分. 一:什么是弱引用 了解弱引用之前,先 ...
- Android开发过程中使用弱引用解决内存泄露的习惯
Java虽然有垃圾回收,但是仍然存在内存泄露,比如静态变量.缓存或其他长生命周期的对象引用了其他对象,这些被引用的对象就会长期不能被GC释放,导致内存泄露. 弱引用(WeakReference)是解决 ...
随机推荐
- Java集合类面试题
java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式. 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最 ...
- 解析HTML利器AngleSharp介绍
解析HTML利器AngleSharp介绍 AngleSharp是基于.NET(C#)开发的专门为解析xHTML源码的DLL组件. 项目地址:https://github.com/FlorianRapp ...
- Pc移植到Mac的技术细节
1.样式不对: 2.布局不对: 3.Mac的菜单替换PC的菜单: Mac的菜单替换PC的菜单: 1)左上角图标没有手动添加且不需要添加的情况下出现,而且点击是Help菜单内容: 2)把HelpBtn和 ...
- 虚拟现实-VR-UE4-LEAP-Motion手势识别
点击打开链接今天到手一个新东西,LEAP手势识别仪. 关于LEAP Leap是一家面向PC以及Mac的体感控制器制造公司. 具体信息百度百科http://baike.baidu.com/link?ur ...
- Python 3基础教程30-sys模块
本文介绍sys模块,简单打印两个重定向输出. 目前使用机会没有,以后实际用到了,再去研究和学习.
- LeetCode 4——两个排序数组中的中位数
1. 题目 2. 解答 2.1. 方法一 由于两个数组都是排好序的,因此首先可以想到的思路就是利用归并排序把两个数组合并成一个有序的长数组,然后直接取出中位数即可. class Solution: d ...
- NO11——01背包
# include <stdio.h> # include <stdlib.h> # include <string.h> # define max(x,y) x& ...
- [译]如何撤销git仓库里的所有修改?
原文来源:https://stackoverflow.com/questions/29007821/git-checkout-all-the-files 问: 如何撤销我在我git仓库所做的所有修改? ...
- UnrealEngine4入门(一) 新建一个c++项目
epic games宣布ue4免费使用(游戏发布之后,每个季度大于3000美元则收取收益的5%)之后,吸引了大批看好VR和AR前景的游戏开发者.不过国内(中文)ue4教程和资料太少,而且一大部分资料都 ...
- C#的Response.BinaryWrite图片乱码问题
今天学习Response对象,该对象的有很多的输出方式,其中有一个binaryWrite可以输出图片,但是在输出图片一开始出现了乱码,后来通过百度得到解决: 代码: FileStream stream ...