Java语言灵巧指针与垃圾回收

豆豆网   技术应用频道   2007年10月29日    社区交流

内容摘要:一些C++ 书上经常告诫程序员:要养成好的习惯,new 与 delete 要成对出现,时刻记住将内存释放回系统。但是,事情只是这么简单吗?

  上面函数的原理就是:不停地删除那些灵巧指针不在CLockMarkArray所包含的指针中的指针,直到所有的指针的灵巧指针都存在于CLockMarkArray所包含的指针中。

  所有被互锁的内存被找出来了,那么,下一步就是如何解锁的问题了。由此,我对灵巧指针引入了一个父类parent_autoptr 如下:

class parent_autoptr
{
public:
parent_autoptr()
{thisAutoMark=0;}
virtual ~parent_autoptr(){}
virtual void Release(){} file://释放指针的拥有权
protected:
int thisAutoMark; file://存放灵巧指针标志
};
  在灵巧指针中,对函数 Release() 进行了重载。
template
class auto_ptr :public parent_autoptr
{
  public:
  virtual void Release(){Remove();}
  auto_ptr()
  {mark=0;pointee=0;thisAutoMark=GetAutoMark();}
  auto_ptr(auto_ptr&rhs);
  auto_ptr(T*ptr);
  ~auto_ptr(){Remove();}
  T*operator->() const;
  operator T*();
  T&operator*()const;
  auto_ptr&operator=(auto_ptr&rhs);
       auto_ptr&operator=(T*ptr);
  private:
       void Remove();
  int GetAutoMark();
  CMutex *GetCMutex();
  void ReadyWrite();
  T*pointee;
  int mark;
  
};

  在 CMarkTable 和 CMark 中对互锁内存进行了释放,如下:

void CMarkTable::DoLockMark()
{
GetLockMark();
RemoveUnlockMark();
  
int size=CLockMarkArray.GetSize();
while(size)
{
CMark* theMark=(CMark*)CLockMarkArray[0];
CLockMarkArray.RemoveAt(0);
if(theMark)
{
  int size2=(theMark->automarkArray).GetSize();
  for(int i=0;i  {
    int automark=(theMark->automarkArray)[i];
    RemoveGroup(automark);
   }
  theMark->Release();
}
size=CLockMarkArray.GetSize();
}
  
Init();
}
  
void CMark::Release()
{
  int size=autoptrArray.GetSize();
  for(int i=0;i  {
parent_autoptr * thePtr=(parent_autoptr *)autoptrArray[i];
thePtr->Release();
  }
}

   到了现在,终于算是大功告成了,我马上把它投入测试当中,发现工作得非常好,即使开辟20至30个线程,程序也工作得很好,并没有抛出异常,而且垃圾回收的功能也非常好。但是,如果线程太多,那么在 CPtrManager 中为了保证线程同步,将会造成瓶颈效应,严重者将会严重影响执行效率。同时,如果每个线程都不停地产生死锁内存,那么,垃圾回收将应接不暇,时间长了,也会造成系统的资源耗尽。

  代码的使用很简单,你只需要将我所附的两个文件加入到工程中,然后,在你的 C*App 中加入如下一段代码就行了:

  CPtrManager thePtrManager;

  这将保证 thePtrManager 在进程最后结束的时候才被析构。

  如果你是在一个新的工程中使用,这就够了,但是,如果你还要使用原来的代码,特别是有指针参数的传递时,那么,你必须注意了。

  如果需要从老代码中接收一个指针,而且这个指针需要你自己释放,那么可以使用灵巧指针,如果不需要释放,那么只能使用一般指针;

  如果需要传递一个指针给老代码,而且这个指针需要你自己释放,那么可以使用灵巧指针,否则,只能使用一般指针。

责编:豆豆技术应用

正在加载评论...