分享
 
 
 

dotnet学习笔记六 - 无用资源回收之三

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

这篇文章接着上一次的来,继续讨论无用资源回收的其它一些话题。

l WeakReference(弱引用)

我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET中提供了WeakReference来实现。弱引用使用起来很简单,看下面的代码:

代码1

Object obj = new Object();

WeakReference wref = new WeakReference( obj );

obj = null;

第一行代码新建了一个新的对象,这里叫它对象A,obj是对对象A的强引用。接着第二行代码新建了一个弱引用对象,参数就是对象A的强引用,第三行代码释放掉对对象A的强引用。这时如果GC进行回收,对象A就会被回收。

怎样在取得对象A的强引用呢?很简单,请看代码2:

代码2

Object obj2 = wref.Target;

if( obj2 != null )

{

… // 做你想做的事吧。

}

else

{

…// 对象已经被回收,如果要用必须新建一个。

}

只要显示的将弱引用的Target属性附值就会得到弱引用所代表对象的一个强引用。不过在使用对象之前要对其可用性进行检查,因为它可能已经被回收了。如果你得到的是null(VB.NET下为Nothing),表明对象已经被回收,不能再用了,需要重新分配一个。如果不是null,就可以放心大胆的用了。

接下来让我们看WeakReference的另外一个版本,请看代码3:

代码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。

l 控制GC行为

.NET提供了System.GC类来控制GC的行为,GC只提供静态方法,无需也不能(GC的构造方法被做成私有)创建它的实例。

GC类提供的最主要一个方法就是Collect,它使自己控制内存回收成为可能。Collect方法有两种版本,void Collect(); 和 void Collect(int);。第二个版本的Collect提供一个参数,让你选择是回收那一代(Generation)以及比其年轻者的对象,也就是说GC.Collect(0)只回收第0代的对象,而GC.Collect(1)则是要回收第0代和第一代的对象。Collect()则是回收所有对象,等同于GC.Collection(GC.MaxGeneration)。MaxGeneration是GC唯一的一个属性,它给出GC的最高代。

GC类提供了另外一个方法来获取某个对象的代值,GetGeneration。代码4给出了一段例子代码,可以让我们更好的理解Generation和GC提供的这两个方法。请看代码4:

代码4

class GCDemoClass

{

~GCDemoClass()

{

Console.WriteLine( "Demo Class Finalizing..." );

}

}

static void Main(string[] args)

{

GCDemoClass inst = new GCDemoClass();

Console.WriteLine( "Generation of demo object:{0} ", GC.GetGeneration( inst ) );

GC.Collect();

Console.WriteLine( "Generation of demo object:{0} ", GC.GetGeneration( inst ) );

GC.Collect();

Console.WriteLine( "Generation of demo object:{0} ", GC.GetGeneration( inst ) );

inst = null;

GC.Collect( 0 );

Console.WriteLine( " After collect generation 0 ..." );

GC.Collect( 1 );

Console.WriteLine( " After collect generation 1 ... " );

GC.Collect( 2 );

Console.WriteLine( " After collect generation 2 ... " );

Console.ReadLine();

}

GCDemoClass实现了一个析构函数,根据我前面文章提到的,编译器会将其变为Finalize方法,在正式回收这个类的实例的内存之前调用。我们把new GCDemoClass()新建的对象叫做对象A,这时它是第0代对象,由于inst保存着一个它的强引用,所以前两次的Collect不会将对象A回收,而随着Collect,对象A的Generation也随之增加,第二次Collect后,对象A成为第二代对象。接下来,inst = null 放弃了对对象A的强引用,但是由于为第二代对象所以Collect(0)和Collect(1)都没有将其回收。终于,Collect(2)被执行,对象A别回收,同时其Finalize方法也被调用。这段代码执行的结果如下:

GC还提供了其他的一些方法,这里就不再讨论了,大家可以去看MSDN。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有