CLR的垃圾回收(GC)机制(1)

为什么垃圾回收?

垃圾回收可以让开发人员从内存管理的麻烦中解放出来,在垃圾回收的环境下,内存申请与对象的创建相关联起来了,当这些对象不再有引用时,占用的内存会被释放。垃圾回收器也提供了析构的接口,用来管理不在托管堆上的非托管资源,开发者可以自定义如何在不需要这些资源时的处理方式,两个主要的目标是:

1,去掉内存管理的bug和陷阱。

2,管理内存的效率等于或高于手动管理的效率。

当前市面上的编程语言用的垃圾回收机制主要有两种:

1,空闲列表管理(C/C++用的方式)

2,引用计数回收(.NET用的方式)

 

空闲列表管理

空闲列表管理是C运行时库的内存管理的基础,同时也是C++内存管理的默认方式,如new和delete关键字。空闲的内存块存储在一个链表里。

空闲列表管理的方式:

1,用空闲列表管理的程序用一个空闲的内存池(用链表组织结构)开始。

2,当申请内存的请求到达时,列表中匹配的内存块会返回。

3,如果空闲列表耗尽,内存管理器会向操作系统申请更多穿闲的内存块添加到链表,或者当申请的内存delete的时候也会这么干。

有以下缺点:

1,申请过程的开销,寻找到一块合适的内存块需要时间。

2,销毁内存的开销,返回内存块到空闲列表需要时间。

3,管理开销,需要通过差分计算和修剪空闲列表来避免内存耗尽,这些工作需要一个单独的线程。

 

引用计数

引用计数回收器把每个对象用一个int型变量(引用的数量)关联起来,当对象创建时,引用计数加1,程序创建一个新的引用到这个对象时,引用计数加1,当程序移除引用时,引用计数减1,当对象的引用计数为0时,对象会被销毁,内存会被回收。

引用计数的缺点是:

1,管理开销,当对象的引用创建或移除时,对象的引用计数必须更新,这意味着频繁的操作类似赋值(a=b)或给函数传一个引用参数。在多核机器上,这个操作会引起同步竞争,并影响缓存命中率。

2,内存使用,对象的引用计数必须存在内存里。

3,正确性,断了环的对象不能被回收,如果程序不再有一个引用直接引用到两个对象,但是这两个对象都互相引用到对方,这时就会发生内存泄露。COM的文档说需要手动打断环。可能描述的不太清楚,看个图吧:

跟踪垃圾回收

首先是标记阶段,这个阶段将所有仍有引用的对象(称作活跃的对象)区分开来。

然后是清理阶段,回收不再使用的对象占用的内存。

最后是紧缩阶段,让活跃的对象在内存中保持连续。

 

标记阶段

此阶段中,GC会遍历程序中所有引用的对象的图,为了防止误报和漏报,GC需要一组起始点,做为遍历的起始点,称之为

建立根之后,这个阶段中垃圾回收器的干的活就容易理解了。GC将遍历过的对象标记一次且仅一次。

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值