• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

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

发布: 2009-9-15 10:28 | 作者: 不详 | 来源: 领测软件测试网 | 查看: 14次 | 进入软件测试论坛讨论

领测软件测试网

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

关键字:数据库设计 HASHTABLE   *g_pTable;/* 哈希表指针 */
    /**   垃圾内存收集算法的初始化函数
            @param  INT nBucketCount——哈希表的bucket的数量       
            @return  INT——返回CAPI_SUCCESS表示成功;返回CAPI_FAILED表示失败
    */
    INT GC_Init(INT nBucketCount)
    {
            g_pTable = HashTable_Create(nBucketCount);
            if ( g_pTable != NULL )
            {
                   return CAPI_SUCCESS;
            }
            return CAPI_FAILED;
    }
    /**   垃圾内存收集算法的内存分配函数
            @param  size——要分派的内存大小,以字节为单位    
            @return——成功返回分配到的内存地址;失败返回NULL
    */
    void *GC_Malloc(size_t size)
    {
            void *p = malloc( size + INT_LEN );
            if ( p == NULL )
            {
                   GC_Collect();
                   p = malloc( size + INT_LEN );
                   if ( p == NULL )
                   {
                           return NULL;
                   }
            }
            HashTable_Insert( g_pTable, p, HashInt);
            *((INT *)p) = 0;
            return (void *)((char *)p+INT_LEN);
    }
    /**   垃圾收集函数,遍历哈希表,将所有引用计数为0的内存释放
            @return  void——无   
    */
    void GC_Collect()
    {
            void *p;
            HashTable_EnumBegin(g_pTable);
            while ( (p = HashTable_EnumNext(g_pTable)) != NULL )
            {
                   INT *pRef = (INT *)p-1;
                   if ( *pRef == 0 )
                   {
                           HashTable_Delete(g_pTable, p, HashInt, IntCompare, NULL);
                           GC_Free(p);
                   }
            }
    }

    注意:上面GC_Malloc()函数里当分配失败后会调用GC_Collect()函数收集垃圾,然后再继续分配内存。

    7. 手工释放及循环引用的释放

    由于引用计数不能处理循环引用的情况,另外可能有些特殊情况下想自己手工将某块内存释放掉,比如申请了一大块内存,用完后不马上释放会浪费很多内存,调用GC_Collect()函数执行的时间开销又比较大,所以有必要设计一个可以让用户手工释放的函数,用户可以通过手工释放函数去释放内存,也可以通过手工释放函数去手工释放循环引用的内存。

    要实现手工释放功能,必须保证在手工释放后GC_Collect()函数不会再对这块内存进行重复释放。从GC_Collect()函数的实现可以看出它是通过对哈希表的遍历来查找引用计数为0的内存进行释放的,因此只要手工释放时将对应的内存从哈希表中删除,GC_Collect()函数就不会重复释放这块内存了。

    下面给出手工释放函数的编码实现。
    /**   垃圾内存收集算法的手工释放内存函数
            @param  void *p——要释放的内存地址
            @return  void——无    
   */
    void GC_ManualFree(void *p)
    {
            void *pFree = (void *)((char *)p-INT_LEN);
            HashTable_Delete(g_pTable, pFree, HashInt, IntCompare, NULL);
            free(pFree);
    }

    可以看出,手工释放实现也非常简单,和GC_Free()的区别就是多了一行哈希表的删除操作而已。使用手工释放函数给用户的使用提供了极大的方便,因为用户可以通过这个函数手工释放循环引用的内存。 

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

TAG: 垃圾 软件测试 算法 用户


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网