C++垃圾回收器的实现
这是一个自己写C++垃圾自己主动回收器,用到的都是标准C++语法。採用了引用计数加mark-sweep的方法。在没有循环引用的情况下,引用计数能够保证垃圾实时得到回收;对于有循环引用的情况下,计数就不能回收了,这时就要用mark-sweep的方法。事实上全然使用mark- sweep的方法也是能够的,但有了引用计数,能够回收大量的非循环引用垃圾,降低最后的mark-sweep时的工作量。
考虑到大家的15分钟阅读热情,在说细节之前,先show一下这个指针怎么使用。顺便提一下,这个指针能够在Windows+MSVC和Linux+GCC下编译,使用。代码下载在http://download.csdn.net/source/267439
SmartPtr<B> b;
SmartPtr<A> a;
ArrayPtr<SmartPtr<A> > ps = new SmartPtr<A>[2];
ps[0] = pA;

{
auto_ptr<MyClass> myObj(new MyClass());
//. . . some other operations
//myObj will be freed automatically



class ObjectWrapper
ObjectWrapper *pWrapper;
T* operator->() {return getTarget();}
const T* operator->() const {return getTarget();}
SmartPtr<T>& operator=(T* p)
ObjectWrapper *old = pWrapper;
pWrapper = WrapperManager::getInstance()->getWrapper<T>(p);
SmartPtr<T>& operator=(const SmartPtr<T> &ptr)
if(pWrapper == ptr.pWrapper)//assign to self
return *this;
pWrapper = ptr.pWrapper;
SmartPtr(const SmartPtr<T>& ptr)
pWrapper = ptr.pWrapper;
pWrapper = WrapperManager::getInstance()->getWrapper<T>(pObj);
operator const T* () const
return getTarget();
return getTarget();
inline const T* getTarget() const
return static_cast<T*> (pWrapper->getTarget());
inline T* getTarget()
return static_cast<T*> (pWrapper->getTarget());
我们前面已经说过了,仅仅使用引用计数进行垃圾回收在有循环引用的情况下就会失效。因此我们须要更有效、更主动的回收算法。在进行更为主动的垃圾回收之前,须要解决的最主要的一个问题就是:什么样的对象是垃圾对象,也就是说,怎样将垃圾对象与非垃圾对象区分开来。 解决问题须要能做到以下两点:
1. 可以界定对象的大小和起始位置。
2. 可以分辨对象的当前使用状态,找出垃圾对象。
SmartPtr<A> pA;
B() { pA = new A(); }
SmartPtr<B> pB = new B();
1) 将全部的指针对象分成根指针和非根指针。可是我们并不知道根指针在什么地方创建,幸好,我们知道非根指针总是位于其它对象内部。我们依次检查pA,pB, 发现pA位于B对象内部,pB不位于不论什么对象内部,因此pB是根指针,pA不是。
这个工作不须要每次进行垃圾扫描时都反复进行,指针对象一旦生成,它的地位是不会变的,不可能从根指针变成非根指针,也不可能相反。仅仅是在两次垃圾扫描的间隙时间,会有新的指针生成,须要检查新生成的指针,确定新生成的指针的类型。
2) 对于每个根指针,訪问它仅仅向的对象,并对该对象内部的全部指针,反复这个过程。从pB,我们訪问到了B对象,然后在B对象内部,我们发现了pA指针,然后反复,从pA指针訪问到A对象,在A对象内部,没有发现不论什么指针。
每次訪问到一个对象,我们就将这个对象标记为可到达状态,因此,A对象和B对象都被标记为可到达状态。
3) 遍历全部的对象,没有被标记为可到达状态的对象就是垃圾,进行清除工作。

到此,一个完整的垃圾回收器就完毕了,是不是非常easy!?
1) 怎样确定一个对象的大小
2) 怎样找到全部的指针对象
3) 假设找到全部的用户对象
4) 假设确定一个指针是否在一个对象内部
5) 怎样调用对象的正确的析构函数进行析构
6) 怎样推断系统是否空暇以便进行垃圾回收
7) 垃圾回收线程与用户线程见的同步问题
8) 怎样处理对象的继承与多态
9) 性能与内存开销
C++垃圾回收器的实现的更多相关文章
- [Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类
目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式 ...
- JVM 垃圾回收器工作原理及使用实例介绍
IBM介绍文档:https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ Java 的新生代串行垃圾回收器中使用了复制 ...
- JVM 垃圾回收器工作原理及使用实例介绍(转载自IBM),直接复制粘贴,需要原文戳链接
原文 https://www.ibm.com/developerworks/cn/java/j-lo-JVMGarbageCollection/ 再插一个关于线程和进程上下文,待判断 http://b ...
- Thinking in java学习笔记之垃圾回收器如何工作
垃圾回收器使得java在堆上分配空间的速度可以和其他语言从堆栈上分配空间的速度媲美.
- C#.Net GC(garbage Collector) 垃圾回收器
以前一直以为gc的原理很简单,也就是分代处理堆数据,直到我的膝盖中了一箭(好吧 直到有天汪涛和我说他面试携程的面试题 关于服务器和 工作站gc 的区别)其实我当时尚不知道 工作站和服务器有什么区别更不 ...
- Java垃圾回收算法和垃圾回收器
基本上 jvm内存回收有三种 基本算法 标记-清除 标记清除的算法最简单,主要是标记出来需要回收的对象,然后然后把这些对象在内存的信息清除.如何标记需要回收的对象,在上一篇文章里面已经有说明. 标记- ...
- Java GC系列(3):垃圾回收器种类
本文由 ImportNew - 好好先生 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 在这篇教程中我们将学习几种现有的垃圾回收器.在 ...
- JVM学习总结三——垃圾回收器
整两天再看调优分析的部分,发现实际运行环境下,还是要考虑配置垃圾回收器,所以这里就加一小章介绍一下. 首先来看一下HotSpot所支持回收期的关系图: 图中可以看到一共有7中垃圾回收器,以中间绿线为界 ...
- Java垃圾回收器
一.Java垃圾回收器要负责完成以下3个任务: 1.分配内存 2.确保被引用对象的内存不被错误回收 3.回收不再被引用的对象的内存空间 二.垃圾回收是一个复杂而又耗时的操作.如果JVM花费过多的时间在 ...
- 面试之C#--垃圾回收器什么时候回收?
每个对象只有在该对象不存在任何引用才会被垃圾回收起回收. 可以调用静态方法System.GC.Collect()垃圾回收器,但是不建议这么做: 用using语句可以有效的自动释放掉资源. 实在没有办法 ...
随机推荐
- JavaScript中==和===的区别(面试题目)
==用于一般比较,===用于严格比较;==在比较的时候可以转换数据类型,===严格比较,只要类型不匹配就返回flase. 举例说明: "1" == true; //true 类型不 ...
- 浅谈 JavaScript 中常用数据及其类型转换
在 JavaScript 中有一些 value 会经常碰到: [] (空数组).{} (空对象).'' (空字符串).undefined.null.0.NaN.Infinite 也会经常碰到数据类型转 ...
- 矩阵分解---QR正交分解,LU分解
相关概念: 正交矩阵:若一个方阵其行与列皆为正交的单位向量,则该矩阵为正交矩阵,且该矩阵的转置和其逆相等.两个向量正交的意思是两个向量的内积为 0 正定矩阵:如果对于所有的非零实系数向量x ,都有 x ...
- asp.net mvc +easyui 实现权限管理(一)
权限是每个企业应用必须的模块,可以简单,也能比较复杂.目前我们公司的权限要求是 能管控页面.字段.按钮.以及数据权限. 正好公司的进销存系统权限模块由我负责.做完后做下记录是个不错的习惯,知识是慢慢积 ...
- Windows win7下VMware Virtual Ethernet Adapter未识别网络解决方法
win7下VMware Virtual Ethernet Adapter未识别网络解决方法[摘] by:授客 QQ:1033553122 问题描述 win7系统下安装VMware,查看网卡适配器设置, ...
- 使用Callable和Future接口创建线程
具体是创建Callable接口的实现类,并实现clall()方法.并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建 ...
- sql 流程函数
create table salary (userid int,salary decimal(9,2)); -- mysqlinsert into salary values(1,1000),(2,2 ...
- SQLServer中DataLength()和Len()两内置函数的区别
最近工作中遇到了个问题:在数据库中声明字段类型时char(4),但实际只存储了‘DCE’三个字母,程序中拼装以该字段作为key的Map中,会把‘DCE’+空格作为其Key,这样造成用没加空格的‘DCE ...
- Hadoop HBase概念学习系列之HBase表的一些设置(强烈推荐好好领悟)(十三)
压缩格式:默认压缩格式是NONE.可选值有GZ.LZO.SNAPPY. 版本数:HBase默认定义为3个版本. 以秒为单位的存活时间TTL:使用对象是行中的列簇,一旦达到过期时间,HBase会删除这些 ...
- randint(1,100) s.add(n) 集合的去重复性