C/C++编程:垃圾回收机制的分类

1060 篇文章 300 订阅

定义

我们把之前使用过,现在不再使用或者没有任何指针再指向的内存空间称为“垃圾”。而将这些“垃圾”收集起来以便再次使用的机制叫做“垃圾回收机制”

在大多数编程语言中,我们都可以看到对垃圾回收特性的支持,如下表所示:

编程语言对垃圾回收的支持情况
C++部分
Java支持
Python支持
C不支持
C#支持
Ruby支持
PHP支持
Perl支持
Hashkell支持

 

分类

垃圾回收的方式虽然很多,但主要可以分为两大类:

基于引用计数的垃圾回收器

简单的说,引用计数主要是使用系统基类对象被引用(引用、指针)的次数。当对象被引用的次数变为0时,该对象既可视为”垃圾“而回收。使用引用计数作垃圾回收算法的一个优点是简单,与其他垃圾回收算法相比,该方法不会造成程序暂停,因为计数的增减与对象的实用是紧密结合的。此外,引用计数也不会读系统的缓存或者交换空间造成冲击,因为被认为“副作用”比较小。但是这种方法很难处理“环形引用”问题,此外由于计数带来的额外开销也不小,所以在使用上也有一定的限制。

基于跟踪处理的垃圾回收器

相比于引用计数,跟踪处理的垃圾回收机制被更广泛的应用。其基本方法是产生跟踪对象的关系图,然后进行垃圾回收。使用跟踪方式的垃圾回收算法主要有以下几种:

标记-清除

这个算法可以分为两部分。首先该算法将程序中正在使用的对象视为“根对象”,从根对象开始查找它们所引用的堆空间,并在这些堆空间上做标记。当标记结束之后,所有被标记的对象就是可达对象或者活对象,而没有被标记的对象就认为是垃圾,在第二步的清扫阶段就会被回收掉。

 

这种方法的特点是活对象不会被移动,但是其存在会出现大量的内存碎片的问题。

 

标记-整理


和上面一样,但是标记完之后,不再遍历所有对象清扫垃圾了,而是将活的对象向“左”靠齐,这就解决了内存碎片的问题

标记-整理方法有个特点就是移动活的对象,因此,相应的,程序中所有对堆内存的引用都必须更新

 

标记-拷贝

这种算法将堆空间分为两个部分:from和to。刚开始系统只从from的堆空间里面分配内存,当from分配满的时候系统就开始回收垃圾:从from堆空间中找出所有活对象,拷贝到to的堆空间中。这样一来,from的堆空间就只剩下垃圾了。而对象被拷贝到to里面之后,在to里面是紧密排列的。接下来只是需要将from和to换一下角色,接着从新的from里面开始分配。

 

标记-拷贝算法的一个问题是堆的利用率只有一半,而且也需要移动活的对象。此外,从某种意义上讲,它也是标记-整理算法。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值