软件测试垃圾回收测试报告,软件测试之之用户层垃圾回收算法[3]

软件测试之之用户层垃圾回收算法[3]

发表于:2009-09-15来源:作者:点击数:

软件测试之之用户层垃圾回收算法[3] 软件测试方法 关键字: 数据库 设计 以上编码便是使用GCPtr类管理引用计数的一个初步实现,当然这里只是为了演示一下如何管理引用计数,并不是全部功能的实现。具体应用中还有许多操作符需要重载,将在后面进行介绍。 4.

软件测试之之用户层垃圾回收算法[3]

关键字:

可以看到在GCPtr的构造函数中,直接由内存地址定位到存放引用计数的位置,将引用计数加1。

析构函数要做的事情也很简单,就是当一个GCPtr类型的变量释放时,直接由要释放的内存地址(已经存放到m_pAddr中)定位到存放引用计数的位置,将引用计数减1。

这种方法在修改引用计数时效率非常高,与哈希表相比无需查表等操作。

5. 需要修改引用计数的情况

实际上,不仅仅是构造函数和析构函数要修改引用计数,牵涉指针的操作基本上都需要修改引用计数,主要有以下三种情况。

1) 当将新地址赋给GCPtr时,需要将原来地址的引用计数减1,新的地址的引用计数加1,这时需要重载运算符“=”号。

2) 当将一个GCPtr赋给另外一个GCPtr时,需要将等号左边的GCPtr指向的内存块的引用计数减1,等号右边的GCPtr指向的内存块的引用计数加1。

3) 当需要对象的副本时,需要调用GCPtr的拷贝构造函数,如将对象当作参数传递给函数,作为函数的返回值等情况都会调用拷贝构造函数。由于复制的对象是指向相同的地址,而复制对象在释放时要调用析构函数,析构函数将引用计数减1,因此需要在拷贝函数里加1以维持引用计数的平衡。

下面给出这几个操作的编码,由于构造函数和析构函数等在前面已经给出,所以这里省略。

template class GCPtr {

public:

T *m_pAddr;    /* 用来记住定义的指针地址便于析构函数使用 */

public:

/* 拷贝构造函数 */

GCPtr(const GCPtr &gcPtr)

{

INT *p = (INT *)gcPtr.m_pAddr-1;

*p += 1;

m_pAddr = gcPtr.m_pAddr;

}

T *operator=(T *t)

{

/* 将原来指向的内存引用计数减1 */

INT *p = (INT *)m_pAddr-1;

*p-= 1;

m_pAddr = t;

/* 将新指向的内存的引用计数加1 */

p = (INT *)t-1;

*p += 1;

return t;

};

GCPtr & operator = (GCPtr &r)

{

/* 将原来指向的内存引用计数减1 */

INT *p = (INT *)m_pAddr-1;

*p-= 1;

m_pAddr = r.m_pAddr;

/* 将新指向的内存的引用计数加1 */

p = (INT *)r.m_pAddr-1;

*p += 1;

return r;

};

};

6. 垃圾收集功能的实现

引用计数的功能实现后,接着要做的就是实现垃圾内存回收,也就是将引用计数为0的内存全部释放后,如何去访问已经分配的内存?必须用一张表来保存所有已分配的内存地址,可以在GC_Malloc()函数分配内存时就将分配的内存地址保存到哈希表里,然后就可以通过对哈希表的遍历来实现对内存垃圾的回收,由于牵涉哈希表的操作,除了修改GC_Malloc()函数外,还需要增加一个初始化函数,在初始化函数里创建哈希表,以下便是实现编码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值