keni:CLR无用内存回收学习笔记(1)

 1 .net中的托管对象

 

1>普通对象:即没有使用系统资源的对象,故没有析构函数。

2>使用系统资源的对象:带析构函数并在其中释放系统资源。

*::系统资源à文件,各种流,网络连接,数据库连接等(内存也是系统资源,但这里的系统资源并不包括内存)

2使用系统资源的5大步骤:

1>     为代表资源的类型分配内存。

2>     初始化资源的状态,请求非内存的系统资源(打开文件,建立数据库连接等)。

3>     通过访问类型的实例及其成员来访问资源。

4>     清空资源状态,释放系统资源。(关闭文件,关闭数据库连接等)。

5>     释放内存。

对于普通对象,只有上面的1>,3>,5>步,而对于使用了系统资源的对象才有上面的全部5步。

CLR默认调用Finalize()来实现第4>步。使用了系统资源的类应该实现Dispose()方法,通过程序员主动调用来释放使用的系统资源,避免CLR调用Finalize()方法带来的性能损失。因为无用内存回收(Garbage Collection 简称GC)运行时,会中止当前程序的执行,大大影响程序的性能。

3引用类型对象在内存中的分配

Class Demo{

       Private int x ;

       Private int y;

       Public Demo(int x,int y)

{

       This.x = x;

       This.y = y;

}

}

Demo d1 = new Demo(1,2);

Demo d2 = new Demo(3,4);

Demo d3 = new Demo(5,6);

New Demo(1,2)所做的事:

1>     托管堆manage heap 中分配指定类型所需字节空间作为存储其对象内存空间并将该空间清0

2>     初始化对象的2个附加成员:指向类型方法表的指针和syncBlockIndex指针。

3>     引起对构造函数的调用。

4>     返回指向新建对象的引用。

如图:

4CLR GC内存分配

当对象过多,manage heap分配光了或者不足分配新的对象时,CLR启动 GC,这时主线程被停止运行。GC将堆中不再被使用的对象占用的内存释放掉,然后整理堆,使剩余空间连续。如果没有可以释放的对象,或者释放了无用对象后内存还是不足,则CLR会抛出一个OutOfMemoryException异常。

5GC如何判断对象不再使用

每一个应用都有一组根,这些根包括了标示托管堆中一组对象的存储单元。被认为是根的对象包括:
1.         所有的全局和静态对象;
2.         一个线成栈中的局部对象和函数的参数;
3.         任何CPU寄存器包含的指针指向的对象;
上面根的列表由JIT和CLR维护并且GC可以访问。
开始无用单元回收后GC就开始遍历根,找到第一个根指向的对象,沿着这个对象向下找,找到这个对象所有引用的对象,以及引用之引用,并将其放入到一个集合中。这一个完成后,就接着找下一个根。一旦GC发现某个对象已经在集合中,就停止这个分支的搜寻以防止重复和引用死循环。
完成后,GC就有了一个所有根可以访问到的对象的集合,这个集合中没有的对象就认为是无用的。如下图:

根:可简单理解为有引用指向他。

简单来说,就是有引用指向他的对象是有用的,而没有引用指向的对象则认为不再使用。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值