GC行为和CLR线程劫持

我正在CLR via C#阅读CLR via C#一书中关于GC的内容,特别是关于CLR何时想要开始收集的内容。 我知道它必须在收集发生之前挂起线程,但它提到它必须在线程指令指针到达安全点时执行此操作。 在它不在安全点的情况下,它会尝试快速找到一个,并通过hijacking线程(在线程堆栈中插入一个特殊的函数指针)来实现。 这一切都很好,花花公子,但我认为托管线程默认是安全的?

我最初认为它可能是指非托管线程,但CLR允许非托管线程继续执行,因为任何使用的对象都应该被固定。

那么,托管线程中的safe point是什么,GC如何确定它是什么?

编辑:

我认为我不够具体。 根据这篇MSDN文章 ,即使调用Thread.Suspend ,在达到safe point之前,线程实际上不会被挂起。 它继续进一步说明safe point是线程执行中可以执行垃圾收集的点。

我想我的问题不清楚。 我意识到一个线程只能在安全点暂停,并且它们必须暂停用于GC,但我似乎无法找到一个明确的答案,关于什么是安全点。 是什么决定了代码中的安全点?

‘安全点’是我们所处的位置:

  1. 不在陷阱中。
  2. 最后不在里面
  3. 不在锁内
  4. 不在p / invoke’d调用内(在托管代码中)。 不在CLR中运行非托管代码。
  5. 内存树是可步行的。

点#5有点令人困惑,但有时候内存树将无法行走。 例如,在优化之后,CLR可能新建一个Object而不是直接将其分配给变量。 根据GC,这个对象将是一个准备收集的死对象。 当发生这种情况时,编译器将指示GC尚未运行GC。

这是msdn上的博客文章,提供了更多信息: http : //blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

编辑:嗯,先生,我错了#4。 请参阅“安全点”部分。 如果我们在ap / invoke(非托管)代码段内,则允许它运行,直到它再次返回到托管代码。

但是,根据这篇MSDN文章 ,如果我们处于CLR代码的非托管部分,那么它将被认为是安全的,并且它们将等待代码返回到托管代码。 (至少我很亲密)。