步骤如下:
1.CLR 会判断当前对象是否包含析构函数,
2.如果包含,则记录对象的地址到所属区域下的析构对象列表中
3.在CLR GC的五个阶段的标记阶段,会判断对象是否存活为1
4.如果不为1,检查对象头中的一直运行析构函数标记是否为1
5.如果为1,则删除析构对象列表的中的记录
6.如果不为1,则把析构对象列表中的记录移动到析构队列或者重要析构队列
7.标记析构队列和重要析构队列的对象为存活对象,即为1
8.等待被析构函数的调用线程调用它
9.移除析构队列或者重要析构队列
10.下一轮GC的回收
**(一)**管理以上的类CFinalize
.Net里面有些对象包含了析构函数的处理, CLR为了保证这些析构对象的调用以及不影响主体GC的分配与回收,在GC_Heap里面定义了管理析构对象的CFinalize类
class CFinalize
{
#ifdef DACCESS_COMPILE
friend class ::ClrDataAccess;
#endif // DACCESS_COMPILE
friend class CFinalizeStaticAsserts;
private:
//adjust the count and add a constant to add a segment
static const int ExtraSegCount = 2;
static const int FinalizerListSeg = NUMBERGENERATIONS+1;
static const int CriticalFinalizerListSeg = NUMBERGENERATIONS;
//Does not correspond to a segment
static const int FreeList = NUMBERGENERATIONS+ExtraSegCount;
PTR_PTR_Object m_FillPointers[NUMBERGENERATIONS+ExtraSegCount];
PTR_PTR_Object m_Array;
PTR_PTR_Object m_EndArray;
size_t m_PromotedCount;
VOLATILE(int32_t) lock;
#ifdef _DEBUG
EEThreadId lockowner_threadid;
#endif // _DEBUG
BOOL GrowArray();
void MoveItem (Object** fromIndex,
unsigned int fromSeg,
unsigned int toSeg);
inline PTR_PTR_Object& SegQueue (unsigned int Seg)