内存的指针的标志。例如:我们用 new 分配了一个 test 指针,假如这个指针的标志 mark=1,那么,这个 test 中的灵巧指针 auto_ptr p 的标志 automark=1。如果一个灵巧指针存在于栈中,那么它的 automark=0。反之亦然,如果一个灵巧指针的 automark 等于一个指针的 mark,那么,该灵巧指针必存在于这个指针所指的内存中。可是,如何得到这个标志呢,请看下面这个函数的实现:
int CPtrManager::GetAutoMark(void *ptr)
{
CSingleLock singleLock(&mutex);
singleLock.Lock(); file://线程同步
int size =m_ptr.GetSize();
for(int i=1;i {
CPtr* theCPtr=(CPtr*)m_ptr[i];
if(theCPtr)
{
int ptrFirst=(int)theCPtr->GetPtr();//得到内存的首指针
int ptrEnd=ptrFirst+theCPtr->GetPtrSize();//得到内存的尾指针
int p=(int)ptr; file://灵巧指针的指针
if(p>=ptrFirst&&p<=ptrEnd)//比较灵巧指针的指针是否在首尾之间
return i;
}
}
return 0;
}
这个函数的原理就在于:如果一个灵巧指针存在于一块内存中,那么该灵巧指针的指针必在这块内存的首尾指针之间。
解决了灵巧指针的位置问题,下一步就是要找出所有被互锁的内存的指针。这个好实现,只要所有拥有这个指针的灵巧指针的 automark > 0 ,那么,这块内存就可能被互锁了(注意只是可能),接着看下面的实现:
class CMark
{
friend class CMarkTable;
public:
CMark(){}
virtual ~CMark(){}
void operator delete(void * p)
{
free(p);
}
void * operator new(size_t size)
{
return malloc(size);
}
void CopyFromCPtr(CPtr* theCPtr); file://从 CPtr 中拷贝相关信息
BOOL bIsNoneInStack(); file://判断拥有该指针的所有灵巧指针是否都不在栈中
void Release(); file://解除该指针的互锁
private:
int m_mark; file://指针的标志
CPtrArray autoptrArray; file://拥有该指针的所有灵巧指针的指针数组
CUIntArray automarkArray;//拥有该指针的所有灵巧指针的标志
};
class CMarkTable
{
public:
CMarkTable(){Init();}
virtual ~CMarkTable(){}
void AddCMark(CMark * theCMark);
BOOL FindMark(int mark);
void Init();
void DoLockMark(); file://处理互锁问题
private:
CPtrArray CMarkArray; file://暂存从CPtrManager 中拷贝过来的指针信息的 CMark 指针数组
CPtrArray CLockMarkArray; file://存放互锁的内存
void GetLockMark(); file://得到所有可能被互锁的内存的 CMark,结果存放于CLockMarkArray
BOOL FindLockMark(int mark); file://判断一个灵巧指针是否存在于CLockMarkArray所包含的指针中
void RemoveUnlockMark();//去除假的互锁内存
void RemoveGroup(int automark);//对互相有联系的相互死锁的内存进行分组
};
Java语言灵巧指针与垃圾回收(6)
时间:2011-01-16
这里又引入了两个类:CMark 和 CMarkTable ,这是为了在处理互锁问题之前,对 CPtrManager 中的 CPtr 进行快速拷贝,以防止影响其它线程的正常运行。其实,这里的 CMark 与 CPtr 没有什么区别,它只是简单地从 CPtr 中拷贝信息,也就是说,它等同于 CPtr 。
为了处理互锁问题,先要把可能被互锁的内存指针找出来,看下面函数的实现:
void CMarkTable::GetLockMark()
{
CLockMarkArray.SetSize(0);
int size=CMarkArray.GetSize();
for(int i=0;i{
CMark * theMark=(CMark*)CMarkArray[i];
if(theMark)
{
if(theMark->bIsNoneInStack())
CLockMarkArray.SetAtGrow(i,theMark);
}
}
}
把这些内存找出来之后,就需要把那些假锁的内存找出来,什么是假锁呢?看下面的例子:
对于指针 ptrA ,如果它的灵巧指针 autoA 存在于指针 ptrB 中, |