您的位置:首页 > 移动开发 > Objective-C

.net 垃圾回收学习[Back To Basics: How does the GC find object references][翻译&&学习]

2011-08-27 16:58 597 查看
From:http://blogs.msdn.com/b/abhinaba/archive/2009/03/03/back-to-basics-how-does-the-gc-find-object-references.aspx

大多数的内存收集算法需要知道被一个给定的对象引用的所有的其他对象,以便能够正确的遍历对象层级树.所有的reference counting, making-sweep and even coping collector 需要了解对象的引用关系。考虑到我在mark-sweep gc中讲到的mark 算法。

void Mark(Object *pObj) { if(!Marked(pObj))//marked returns the marked flag from object { MarkBit(pObj);// marks the flag in obj header //get list of reference that the current object has //and recursively mark them as well //注意 ObjectCollection children = pObj->GetChildren(); for(int i=0; i < children.Count(); i++) { Mark(children[i]);// recursively call mark } } }

注意这段话(ObjectCollection children = pObj->GetChildren()). 假如给定了一个对象,我们要能够定位到所有的被他引用的对象(或者任何在它的对象引用图中的子)。通常有两种基本方式:

Conservative GC(保守)

假如GC是以DLL形式的被加载到当前的系统中,并且没有比较简单的方式来修改运行时状态,此时Conservative system 被使用。一个Conservative GC 认为在Heap上的每一个Bit都是一个有效的指向另一个堆上对象的引用。 在给定一个对象的情况下,GC需要以下基本的信息:

The size of the Object(对象的大小)

Alignment of pointers(let assume it to be 32bit for our case )指针的对齐(应该是指指针的大小,比如说4个字节的指针)。

所以,一旦GC得到一个对象的指针pObj ,它会把在pObj和pObj + sizeof(Object)中的所有的32bit的模式认为是指向另外的对象的引用。然后使用基本的消除方法比如说其职(32bit的空间)是不是在系统当前的Heap中的一个有效的地址。假如没有任何不匹配的逻辑被匹配,那么对象被认为是一个引用。

即使这种方法看上去有点极端,它仍然工作的非常好,唯一的缺陷是可能返回错误的位置导致垃圾回收没有进行(比如说,32bit的值正好和heap上的某个对象的地址相匹配)。

Precise GC(精确模式)

在Precise GC模式下,GC精确地知道给定的对象持有的每个引用,只有当运行时产生并且保留这种信息的时候,GC的Precise GC模式才有可能实现。这里有不同的方式实现Precise GC模式,这里将迅速的过一下其中的一种模式:

每个对象都有一个Object header, Object header 包含一个指向它的type/class descriptor的指针。这个class descriptor 有一个特殊的32位的字段,这个字段叫做ReferenceMap,存储着给定类型的引用信息。





所以当在给定一个对象的指针pObj的时候,GC取出来Object Header,据此得到Object的Class Descriptor ponter, 随后即可得到ReferenceMap。为了完成上述的步骤,GC只需要知道Object Header和Class descriptor的结构即可,不需要其他的类型信息。

所有的引用都是32-bit对齐的,假如ReferenceMap将每个32-bit 的独享保留一个Bit,假如这个Bit被设置了,意味着包含一个相应的32-bit的引用。

以下列Class为例:

class Mytype

{

public char a;

public char b;

public AnohterType t1;

public AnotherType t2;

}


这个Class的内存结构大体上如下所示:





头两个Char每个占据了16bit, 随后有三个32位的内存块,有第一个和第三个(t1和t3)指向其他对象的32位的引用, I不是这种类型。

GC需要知道这个对象从32-bit到96th-bit的内存空间是否是引用,这个信息是在refMap字段中编码的。它包含了一个bit-pattern 00000000000000000000000000001010LSB是从对象的第一个32位的成员开始,随后是第二个32位的成员。

所以RefMap的一个Bit被设置意味着(pObj+1*32)的地方是一个引用。加入那个值不是NULL,那么GC能够翻出来他,从而得到被pObj引用持有的T1对象。

很明显, refMap的最大大小能够编码的是32*4=128Bytes, 不明白大于这个大小的是如何进行处理的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐