ガベージコレクショのメモリ管理の基本

1,参照はオブジェクト側から。
2,メモリの開放はヒープ側から。

参照はGCPtrであるオブジェクト側から確認します。std::setにinsert,delすることでオブジェクトの生存を管理します。オブジェクトが必要なくなりdelされても、Tは別のオブジェクトが参照しているかもしれないので、削除せずそのままにします。実際の削除はあるタイミングでスレッドを止めてオブジェクト側から、参照されているTの前に付くGCHeaderのstatにフラグを付け、ヒープ側からGCMHeaderのstatを見て参照されていないTのすべてのデストラクタを起動し実際にフリーにします。

GCPtrの場合メモリ上では GCHeader+CStringの形で存在します。
ヒープ側では、GCHeaderの認識はできますがTについては型のないvoid*のデータとして扱います。

マーク&スイープのGCコレクションをこの方法で作成しましたが、以外と簡単だったのでコピーGCのコレクションも作成してみましたが、もっと簡単でした。

実際に使用するために確認しなければならないテストの方が難しそうです。


struct GCMHeader
{
GCMHeader():stat_(0),size_(0),destroy_(NULL){}

GCDestroy destroy_;
UINT stat_;
UINT size_;

void* get(){return ((GCMHeader*)this + 1);}
};

template
class GCPtr : public GCObject
{
public :
GCPtr():mem_(NULL)
        {
          GCAdd(this);
        }

GCPtr(T* p):mem_(p)
{
GCMHeader* u = (GCMHeader*)mem_ - 1;
u->destroy_ = GCAllocate::destructor::destroy; // オブジェクト側からTのデストラクタを設定

GCAdd(this); // staticなstd::setへinsert
}
~GCPtr()
{
GCDel(this);
}
const GCPtr& operator =( const GCPtr& p )
{
mem_ = p.mem_;
return *this;
}
        T* get(){ return mem_; }
...
protected :
T* mem_;
};