垃圾回收

垃圾回收

  1. 1.       托管和非托管资源

托管资源

由CLR管理的存在于托管堆上的资源

       // Common Language Runtime (CLR) 译为「通用语言运行时」

关键点:由CLR管理,在托管堆上

托管资源的回收工作是不需要人工干预的,CLR会在合适的时候调用GC(垃圾回收器)进行回收 

非托管资源

非托管资源是不由CLR管理

例如:Image Socket,StreamWriter, Timer,文件句柄,,GDI资源,数据库连接等等资源

非托管资源GC[Garbage Collection]是不会自动回收的,需要手动释放

  1. 2.       垃圾回收的目的

整理内存,回收不再使用的对象,释放内存以提高效率

  1. 3.       托管资源的垃圾回收

CLR的一个核心功能

垃圾回收

垃圾回收器

只回收托管堆中的内存资源,不回收其他资源(数据库连接、文件句柄、网络端口等)

//非托管资源GC[Garbage Collection]是不会自动回收的,需要手动释放

什么样的对象才会被回收?

答:没有变量引用的对象

什么时间回收?

  1. 去饭店吃饭,什么时候收盘子呢?
  2. 系统回收,具体何时回收垃圾由系统自行确定,并不是即时执行回收的
  3. 手动调用垃圾回收器GC.Collect();,不建议使用,垃圾回收时会会使程序暂停,影响程序性能

垃圾回收器中“代”的概念:

  1. 共3代:第0代、第1代、第2代
  2. 回收频率:第0代最高,其次第1代,再次第2代
  3. 越老的对象生存几率越大
  4. 第0代满则回收第0代;第1代满则回收第0代与第1代,不满则不回收;第2代是顶级代,超过第2代内存则会报内存溢出

  标记-压缩回收机制

弱引用

  1. 问题:如果有一个比较耗费资源的对象,每次实例化都很麻烦,如果指向null后又使用了,则可以先到内存中找一找,看有没有回收,如果没回收则直接使用
  2. 解决:使用弱引用WeakReference对象(代码见备注)
  3. 弱引用:告诉GC可以回收,如果再次访问时还没有回收,则可以拿过来继续使用;如果回收了则获取不到了
  4. 使用情况[原因]:对象的创建比较耗费时间,如从数据库中取出来100条数据存入List中,这时List对象最好使用弱引用

//将对象存入弱引用:

Person p=new Person();

p.Age=18;

WeakReference wk=new Reference(p);  //弱引用

P=null;

//从弱引用中获取对象:

object pnew=wk.Target;

if(pnew!=null)

  {

     Console.WriteLine((Person)pnew).Age);

  }

else

  {

    Console.WriteLine("对象已经被回收!!!");

  }

  1. 4.       非托管资源的垃圾回收

方法一:使用Dispose()方法

对象要继承IDisposable接口,也就会自动调用Dispose方法

推荐使用using语法进行使用,最终不用手动释放资源

方法二:使用Finalize()方法

允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作

此方法的本质就是析构函数

 

原文地址:https://www.cnblogs.com/liushen/p/3292765.html