网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 网络学院 >> 程序设计 >> VC编程 >> 文章正文
  GC实现            【字体:
GC实现
作者:佚名    文章来源:不详    点击数:    更新时间:2007-9-12    
//垃圾回收设想
//回收策略,内存整理和多线程问题暂不考虑

//必要的限制:
//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)
    
{