fre*_*low 5 c# clr garbage-collection pass-by-reference
如果我通过引用函数传递数据成员会发生什么,并且在该函数运行时,垃圾收集器开始运行并将包含数据成员的对象移动到内存中?
class SomeClass
{
int someDataMember;
void someMethod()
{
SomeClass.someFunction(ref someDataMember);
}
static void someFunction(ref int i)
{
i = 42;
int[] dummy = new int[1234567890];
// suppose the Garbage Collector kicks in here
i = 97;
}
}
Run Code Online (Sandbox Code Playgroud)
在垃圾收集过程中,CLR如何确保引用参数不会失效?他们是否像课程参考一样调整?
好吧,垃圾收集者的生活并不容易.但它知道如何处理这样的内部指针.很好地隐藏在C#和VB.NET等托管语言中,它在C++中可见,其中内部指针可以通过语言语法轻松生成.C++ Primer成名的Stan Lippman有一篇关于它们的博客文章,给出了interior_ptrC++/CLI中可用关键字的一些主要动机.
抖动比这更进一步,它将引用标记为GC_CALL_INTERIOR,指示可能是内部指针的参数的特定情况.您可以使用SSCLI20发行版中提供的源代码查看GC内部的处理方式.它不是非常复杂,来自gcsmp.cpp,GCHeap :: Relocate()方法的片段:
if (flags & GC_CALL_INTERIOR)
{
if ((o < gc_heap::gc_low) || (o >= gc_heap::gc_high))
{
return;
}
o = gc_heap::find_object (o, gc_heap::gc_low);
offset = (BYTE*)object - o;
}
Run Code Online (Sandbox Code Playgroud)
因此,简而言之,通过检查指向GC堆段下限/上限的指针,发现它不能是引用引用类型对象成员的指针,这是一个非常快速的测试.然后进行一些挖掘,将内部指针映射到包含该成员的对象.看看SSCLI20源代码,看看那段代码.