GC实现

// 垃圾回收设想
// 回收策略,内存整理和多线程问题暂不考虑

// 必要的限制:
// 1、所有具备垃圾回收功能的类都必须派生自gcBase
// 2、只能通过gcPtr和gcSPtr来访问gcBase(和派生类),
//     也就是说,直接申明gcBase的全局变量和通过原生指针gcBase *都不是合法的
//     使用gcBase的全局变量会导致在垃圾回收代码delete一个无效的内存
//     通过原生指针gcBase *访问gcBase会导致垃圾回收提前删除这个对象
// 3、gcPtr和gcSPtr原则上都必须知道是哪个gcBase拥有它。
//     gcSPtr的拥有者设置成一个全局的gcBase的实例,因此,gcSPtr应该在全局变量和栈变量上使用
// 这些限制类似于C++/CLI (vs2005)的垃圾回收
// --------------------------------------------------------------------------------------------------

#pragma  warning(disable : 4355)

// 垃圾回收策略
struct  gcTactic
{
    
virtual ~gcTactic();
    
virtual void Check() = 0;

    
static gcTactic *    sm_pInstance;
    
static void CheckGarbage()
    
{
        sm_pInstance
->Check();
    }

}
;

struct  gcBase;

// GC指针基类
struct  __gc_Ptr__
{
    friend gcBase;
private:
    gcBase 
*        __gc_m_pParent;
    __gc_Ptr__ 
*    __gc_m_pNext;
    __gc_Ptr__ 
*    __gc_m_pPrev;

    
void __InitLink(gcBase * pParent);
    
static void * operator new (size_t);
    
static void operator delete (void *);
    
static void operator delete (void *,size_t);
protected:
    gcBase 
*        __gc_m_pRef;
public:
    
~__gc_Ptr__();

    __gc_Ptr__(gcBase 
* pParent)
    
{
        __gc_m_pRef 
= 0;
        __InitLink(pParent);
    }

    __gc_Ptr__(gcBase 
* pParent,gcBase * __r)
    
{
        __gc_m_pRef 
= __r;
        __InitLink(pParent);
    }

    __gc_Ptr__(gcBase 
* pParent,const __gc_Ptr__ & __r)
    
{
        __gc_m_pRef 
= __r.__gc_m_pRef;
        __InitLink(pParent);
    }

    __gc_Ptr__ 
& operator = (gcBase * __r)
    
{
        __gc_m_pRef 
= __r;
        
return *this;
    }

    __gc_Ptr__ 
& operator = (const __gc_Ptr__ & __r)
    
{
        __gc_m_pRef 
= __r.__gc_m_pRef;
        
return *this;
    }

}
;

// 所有具备垃圾回收功能的类都必须派生自此类
struct  gcBase
{
    friend __gc_Ptr__;
private:
    
static volatile long __gc_sm_nObjectCounter;
    
static size_t    __gc_sm_nScanCounter;
    
static gcBase    __gc_sm_Root;
    
static gcBase *    __gc_sm_pFirst;
    
static void __gc_Mark(gcBase * obj);

    size_t            __gc_m_nScanCounter;
    __gc_Ptr__ 
*    __gc_m_pFirstPtr;
    gcBase 
*        __gc_m_pNext;
    gcBase 
*        __gc_m_pPrev;

public:
    
static void GarbageCallback();

    gcBase();
    
virtual ~gcBase();
}
;

// 当作成员变量的GC指针
template < class  _Ty >
struct  gcPtr :  public  __gc_Ptr__
{
    typedef _Ty 
* _Pty;
    typedef gcPtr
<_Ty>    this_type;

    gcPtr(gcBase 
* pParent)
        :__gc_Ptr__(pParent)
    
{
    }

    gcPtr(gcBase 
* pParent,_Pty __r)
        :__gc_Ptr__(pParent,__r)
    
{
    }

    gcPtr(gcBase 
* pParent,const this_type & __r)
        :__gc_Ptr__(pParent,__r)
    
{
    }


    this_type 
& operator = (_Pty __r)
    
{
        __gc_m_pRef 
= __r;
        
if(__gc_m_pRef == NULL)
            gcTactic::CheckGarbage();
        
return *this;
    }

    this_type 
& operator = (const this_type & __r)
    
{
        __gc_m_pRef 
= __r.__gc_m_pRef;
        
if(__gc_m_pRef == NULL)
            gcTactic::CheckGarbage();
        
return *this;
    }

    
operator _Pty () const{
        
return (_Pty)__gc_m_pRef;
    }

    _Pty 
operator -> () const{
        
return (_Pty)__gc_m_pRef;
    }

    _Pty 
* operator & (){
        
return (_Pty *)&__gc_m_pRef;
    }

    
const _Pty * operator & () const{
        
return (const _Pty *)&__gc_m_pRef;
    }

}
;

// 在栈上使用的GC指针
template < class  _Ty >
struct  gcSPtr :  public  gcPtr < _Ty >
{
    typedef gcPtr
<_Ty>    base_type;
    typedef gcSPtr
<_Ty>    this_type;

    gcSPtr()
        :gcPtr
<_Ty>(NULL)
    
{
    }

    gcSPtr(_Pty __r)
        :gcPtr(NULL,__r)
    
{
    }

    gcSPtr(
const base_type & __r)
        :gcPtr(NULL,__r)
    
{
    }

    gcSPtr(
const this_type & __r)
        :gcPtr(NULL,__r)
    
{
    }

    
~gcSPtr()
    
{
        
if(__gc_m_pRef != NULL)
        
{
            __gc_m_pRef 
= NULL;
            gcTactic::CheckGarbage();
        }

    }

    this_type 
& operator = (_Pty __r)
    
{
        base_type::
operator = (__r);
        
return *this;
    }

    this_type 
& operator = (const base_type & __r)
    
{
        base_type::
operator = (__r);
        
return *this;
    }

}
;

// --------------------------------------------------------------------------------------------------
// 另外一种设想————还没有想好

struct  __gcHeap__
{
    
static __gcHeap__ sm_Heap;
}
;

#define  gc_new new(__gcHeap__::sm_Heap)
 
#include  " gcbase.h "
#include 
< windows.h >

#ifndef NULL
#define  NULL 0
#endif

struct  gcDefaultTactic :  public  gcTactic
{
    
volatile long m_bChecking;
    gcDefaultTactic()
    
{
        m_bChecking 
= 0;
    }

    
virtual ~gcDefaultTactic()
    
{
    }

    
virtual void Check()
    
{
        
if(m_bChecking)
            
return ;
        InterlockedExchange(
&m_bChecking,1);
        gcBase::GarbageCallback();
        InterlockedExchange(
&m_bChecking,0);
    }

}
;

gcTactic::
~ gcTactic()
{

}


gcTactic 
*  gcTactic::sm_pInstance  =  NULL;


volatile   long     gcBase::__gc_sm_nObjectCounter  =   0 ;
size_t    gcBase::__gc_sm_nScanCounter 
=   1 ;
gcBase    gcBase::__gc_sm_Root;
gcBase 
* gcBase::__gc_sm_pFirst  =  NULL;

void  __gc_Ptr__::__InitLink(gcBase  *  pParent)
{
    
if(pParent == NULL)
        pParent 
= &gcBase::__gc_sm_Root;
    __gc_m_pParent 
= pParent;

    __gc_m_pNext 
= __gc_m_pParent->__gc_m_pFirstPtr;
    __gc_m_pPrev 
= NULL;
    
if(__gc_m_pNext != NULL)
        __gc_m_pNext
->__gc_m_pPrev = this;
    __gc_m_pParent
->__gc_m_pFirstPtr = this;
}


__gc_Ptr__::
~ __gc_Ptr__()
{
    
if(this == __gc_m_pParent->__gc_m_pFirstPtr)
        __gc_m_pParent
->__gc_m_pFirstPtr = __gc_m_pNext;
    
if(__gc_m_pNext)
        __gc_m_pNext
->__gc_m_pPrev = __gc_m_pPrev;
    
if(__gc_m_pPrev)
        __gc_m_pPrev
->__gc_m_pNext = __gc_m_pNext;
}


struct  __gcFinalGarbageCallback
{
    
~__gcFinalGarbageCallback()
    
{
        gcBase::GarbageCallback();
    }

}
;

gcBase::gcBase()
{
    
static __gcFinalGarbageCallback __final_gc;
    
static gcDefaultTactic __celue;
    
if(gcDefaultTactic::sm_pInstance == NULL)
        gcDefaultTactic::sm_pInstance 
= &__celue;

    __gc_m_nScanCounter 
= 0;
    __gc_m_pFirstPtr 
= NULL;

    __gc_m_pNext 
= __gc_sm_pFirst;
    __gc_m_pPrev 
= NULL;
    
if(__gc_m_pNext != NULL)
        __gc_m_pNext
->__gc_m_pPrev = this;
    __gc_sm_pFirst 
= this;

    InterlockedIncrement(
&__gc_sm_nObjectCounter);
}


gcBase::
~ gcBase()
{
    
if(this == __gc_sm_pFirst)
        __gc_sm_pFirst 
= __gc_m_pNext;
    
if(__gc_m_pNext)
        __gc_m_pNext
->__gc_m_pPrev = __gc_m_pPrev;
    
if(__gc_m_pPrev)
        __gc_m_pPrev
->__gc_m_pNext = __gc_m_pNext;
    __gc_m_pFirstPtr 
= NULL;

    InterlockedDecrement(
&__gc_sm_nObjectCounter);

    gcTactic::CheckGarbage();
}


void  gcBase::__gc_Mark(gcBase  *  obj)
{
    obj
->__gc_m_nScanCounter = __gc_sm_nScanCounter;

    
for(__gc_Ptr__ * p = obj->__gc_m_pFirstPtr; p;)
    
{
        obj 
= p->__gc_m_pRef;
        p 
= p->__gc_m_pNext;

        
if(obj == NULL)
            
continue;
        __gc_Mark(obj);
    }

}


void  gcBase::GarbageCallback()
{
    
++__gc_sm_nScanCounter;
    __gc_Mark(
&__gc_sm_Root);

    
for(gcBase * p = __gc_sm_pFirst; p; )
    
{
        gcBase 
* temp = p->__gc_m_pNext;
        
if(p->__gc_m_nScanCounter != __gc_sm_nScanCounter)
            delete p;
        p 
= temp;
    }

}


// --------------------------------------------------------------------------------------------------

__gcHeap__ __gcHeap__::sm_Heap;
//  testgc.cpp : 定义控制台应用程序的入口点。
//

#include 
" stdafx.h "
#include 
" gcbase.h "

struct  BTree :  public  gcBase
{
    gcPtr
<BTree>    m_pLeft;
    gcPtr
<BTree>    m_pRight;
    
int                m_nID;

    BTree(
int id)
        :m_pLeft(
this)
        ,m_pRight(
this)
    
{
        m_nID 
= id;
    }

}
;

void  BuildTree( int   & id,gcPtr < BTree >   &  tree, int  nDepth)
{
    
if(nDepth)
    
{
        tree
->m_pLeft = new BTree(id++);
        BuildTree(id,tree
->m_pLeft,nDepth - 1);
        tree
->m_pRight = new BTree(id++);
        BuildTree(id,tree
->m_pRight,nDepth - 1);
    }

}


void  PrintTree(gcPtr < BTree >   &  tree)
{
    std::cout 
<< tree->m_nID << std::endl;
    
if(tree->m_pLeft != NULL)
    
{
        PrintTree(tree
->m_pLeft);
        tree
->m_pLeft = NULL;
    }
    
    
if(tree->m_pRight != NULL)
        PrintTree(tree
->m_pRight);
}


int  _tmain( int  argc, _TCHAR *  argv[])
{
    
//如果有内存泄露,CRT就可以通过VC的输出窗口报告出来
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    
int id = 0;
    gcSPtr
<BTree> tree(new BTree(id++));
    BuildTree(id,tree,
5);
    PrintTree(tree);

    gcBase::GarbageCallback();        //这个时候不可能发生垃圾回收
    tree = NULL;                    //所有垃圾都会被回收

    
return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值