辅导:C++基础(GC)
来源:优易学  2011-11-11 13:09:13   【优易学:中国教育考试门户网】   资料下载   IT书店
  JAVA,C sharp的supporter经常拿语言特有的垃圾回收器说事.C++是万能的!当然前提是使用它的人必须先是全能的.
  下例是以青年人网站现在浅薄的C++掌握水平所实现的基于标记-清除算法的GC.如果类对象想实现自动回收其内存,其必须派生自Collectable类,并且实现Collectable的GetReference虚函数,由于我是无法预知派生类的指针或引用成员变量,所以采用template设计模式依赖倒置.
  简单示意:
  void Class1::GetReference()
  {
  m_reftoClass2 ->doMark();//标记其引用对象
  or return;//如果没有引用对象,同时递归终止
  }
  #ifndef _GC
  #define _GC
  #pragma once
  #include <vector>
  #include <iterator>
  using namespace std;
  class Collectable;
  class GarbageCollector{
  typedef vector<Collectable *> MEMPOOL;
  public:
  //the public interface to the client
  static GarbageCollector *GetInstance(void)
  {
  if(!iSelf)
  return (iSelf = new GarbageCollector());
  return iSelf;
  }
  static void Add2GC(Collectable *obj);
  void GarbageCollection(Collectable *rootObj);
  private:
  GarbageCollector()
  {
  }
  void Mark(Collectable *obj);
  void Sweep();
  MEMPOOL iMemPool;
  static GarbageCollector *iSelf;//the only instance of GC class
  };
  class Collectable{
  friend class GarbageCollector;
  public:
  Collectable(bool mark = 0):iMarkBit(mark){}
  virtual ~Collectable(){}
  void doMark(void)
  {
  if(!iMarkBit)
  {
  iMarkBit = true;
  GetReference();
  GarbageCollector::Add2GC(this);
  }
  }
  virtual void GetReference() = 0;
  protected:
  bool iMarkBit;//Mark for GC
  };
  GarbageCollector *GarbageCollector::iSelf = NULL;
  void GarbageCollector::Add2GC(Collectable *obj)
  {
  (iSelf->iMemPool).push_back(obj);
  }
  void GarbageCollector::Mark(Collectable *obj)
  {
  if(obj)
  obj->doMark();
  }
  void GarbageCollector::Sweep()
  {
  for(MEMPOOL::iterator vIter = iMemPool.begin(); vIter != iMemPool.end();)
  {
  Collectable *temp = *vIter;
  //Here it's the data used by other data
  if(temp->iMarkBit)
  {
  temp->iMarkBit = false;
  vIter++;
  }
  else
  {
  //Discard the useless data block and adjust iterator to proper position
  vIter = iMemPool.erase(vIter);
  //free the memory or push the space into memory pool
  delete temp;
  }
  }
  }
  void GarbageCollector::GarbageCollection(Collectable *rootObj)
  {
  if(rootObj)
  {
  Mark(rootObj);
  Sweep();
  }
  }
  #endif
  本例其实存在隐患,即有可能stack overflow.因为doMark->GetReference->doMark... ...递归扫描,而且Collectable和GarbageCollector双向耦合,耦合度高.另外在清除标记为0(即不再被引用的对象)时,只是简单释放给系统堆.如果内重载operator delete(void *)使之仅仅归还给Memory Pool其价值更高.其实在寸土寸金的嵌入式设备中,内寸很容易耗尽,GC的价值应该被集成到系统的内存管理器中,哎,继续学习Symbian中,因为还没有看到它的内存管理策略是什么.

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训