而 ptrB 的灵巧指针 autoB 又存在于 ptrA 中,那么 ptrA 和 ptrB 是真锁,但是如果ptrB 的灵巧指针 autoB 存在于指针 ptrC 中,而 ptrC的灵巧指针 autoC 存在于栈中,那么, ptrA 和 ptrB 属于假锁。怎么找出假锁的内存呢?看下面函数的实现:
void CMarkTable::RemoveUnlockMark()
{
CUIntArray UnlockMarkArray;
BOOL bNoneRemoveed;
do
{
bNoneRemoveed=TRUE;
UnlockMarkArray.SetSize(0);
int size=CLockMarkArray.GetSize();
for(int i=0;i{
CMark * theMark=(CMark*)CLockMarkArray[i];
if(theMark)
{
int size1=(theMark->automarkArray).GetSize();
for(int j=0;j {
int mark=(theMark->automarkArray)[j];
if(!FindLockMark(mark)) file://判断灵巧指针是否存在于CLockMarkArray所包含的指针中
{
UnlockMarkArray.InsertAt(0,i); file://record to remove
bNoneRemoveed=FALSE;
break;
}
}
}
else
{ UnlockMarkArray.InsertAt(0,i);
bNoneRemoveed=FALSE;
}
}
int size2=UnlockMarkArray.GetSize();
for(int k=0;k{
int m=UnlockMarkArray[k];
CLockMarkArray.RemoveAt(m);
}
}while(!bNoneRemoveed);
}
Java语言灵巧指针与垃圾回收(7)
时间:2011-01-16
上面函数的原理就是:不停地删除那些灵巧指针不在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;
};
Java语言灵巧指针与垃圾回收(8)
时间:2011-01-16
在 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 中为了保证线程同步,将会造成瓶颈效应,严重者将会严重影响执行效率。同时,如果每个线程都不停地产生死锁内存,那么,垃圾回收将应接不 |