.NET GC垃圾回收机制与强弱引用

一、GC全称

答:Garbage Collector(垃圾收集器)

二、GC有什么用?(垃圾回收的目的)

答:主要就是为了提高内存利用率

三、GC回收哪些垃圾?

答:只回收“托管堆中的内存资源”,没有引用的对象。不回收“栈”上的资源(比如值类型)。

四、什么时候回收?

答:不确定,当程序需要新内存的时候执行回收。

五、GC垃圾回收机制(重点!)

答:引入“代”的概念,

①总共有三代,0~2代。

②每次新建对象都在第0代中。

③每代有固定大小。

图解:新建了a、b、c、d四个对象,第0代内存满了,但此时又新建了一个e对象,那这个时候会发生什么?e对象会被放在哪里?1代里吗?还是2代?

在这里插入图片描述

错!不会放在1代里,也不会放在2代里。这个时候会触发“垃圾回收”,CLR会去遍历这a、b、c、d这四个对象,打上标记。假设a和b对象已经没有被引用了,c和d还在被引用,那a和b就会被当做垃圾回收掉,c和d就会被放到1代里,e也就进入0代了。
在这里插入图片描述
进过GC回收后,就变成了下面这样:

在这里插入图片描述

如此往复。

备注:这个叫“自动回收”,肯定有小朋友会问,那是不是可以手动回收。答案是肯定的,比如析构函数就可以达到这个目的。还不知道什么是“析构函数”的小朋友,请偷偷出门去自行百度。

六、弱引用

人就是这样,得不到的永远在骚动,得到的有恃无恐。当失去了,才追悔莫及。假如对象要被回收了,但是我又想再次用这个对象,该怎么办?这个时候就出来了这个–“弱引用”。

为什么需要弱对象呢?因为,有一些数据创建起来很容易,但是却需要很多内存。

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

6.1:什么是弱引用

了解弱引用之前,先了解一下什么是强引用

例如 : Object obj=new Object(); 就是一个强引用,内存分配一份空间给用以存储Object数据,这块内存有一个首地址,也就是obj所保存的数据,内存分配的空间中不仅仅保存着Object对象信息,还保存着自己(Object本身)被引用的次数。

当一个对象被强引用的形式创建的时候,本身被引用的次数已经为1.

接着Object o=obj; 这句代码执行之后,obj指向的Object的存储空间已经被引用了2次,所以Object保存的被引用数值为2.

总结:强引用最终导致的结果就是被引用的对象的被引用次数+1;

相反的弱引用就是不会对被引用对象的被引用次数有任何影响。

6.2:弱引用有什么作用

防止内存泄露。


Object obj=new Object();

当你在通过异步的形式访问网络上面的资源的时候,需要的时间可能会比较长,在数据返回之前,用户很可能转向了其他的页面,如果异步访问的对象(obj)对本地的一个对象(Object)是强引用的话,那么在这个异步访问对象(obj)被释放之前,也即在数据被回调之前,这个被引用的对象(Object)是不会被销毁的,这样一来,就导致内存一直被占用。

  WeakReference weakObj=new WeakReference(Object);

此时就可以使用弱引用,弱引用对象(weakObj)发出异步请求,在回调之前,如果用户要转到其他的页面,这个被引用的对象(Object)是可以被释放的,这样子就不会出现内存一直被占用的现象。

6.3:怎样使用弱引用

弱引用类: WeakReference //有两个重载的构造函数

WeakReference WeakObj=new WeakReference(Object); //弱引用方式

IsAlive属性是判断此弱引用对象所引用的对象是否还存在,存在:IsAlive=True;
Target属性是设置该弱引用对象所引用的数据对象的值

弱引用使用起来很简单,看下面的代码:

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,就可以放心大胆的用 了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值