我在书中读到关于GC的内容CLR via C#
,特别是关于 CLR 何时想要开始收集。我知道它必须在收集发生之前挂起线程,但它提到当线程指令指针到达安全点时它必须执行此操作。在它不在安全点的情况下,它会尝试快速到达安全点,并且这样做是通过hijacking
线程(在线程堆栈中插入特殊函数指针)。这一切都很好,但我认为默认情况下托管线程是安全的?
我最初以为它可能指的是非托管线程,但 CLR 允许非托管线程继续执行,因为任何正在使用的对象无论如何都应该被固定。
那么,什么是safe point
在托管线程中,GC 如何确定那是什么?
EDIT:
我认为我说得不够具体。根据这篇 MSDN 文章 http://msdn.microsoft.com/en-us/library/678ysw69.aspx,即使当Thread.Suspend
被调用时,线程实际上不会被挂起,直到safe point
到达了。它继续进一步指出safe point
是线程执行中可以执行垃圾收集的点。
我想我的问题不清楚。我意识到线程只能在安全点挂起,并且必须在 GC 时挂起它们,但我似乎无法找到关于什么是安全点的明确答案。什么决定代码中的点是安全的?
“安全点”是我们所处的位置:
- 不在 catch 块中。
- 不在finally里面
- 不在锁内
-
不在 p/invoke'd 调用内(在托管代码中)。 不在 CLR 中运行非托管代码。
- 记忆树是可行走的。
第 5 点有点令人困惑,但有时内存树将无法行走。例如,优化后,CLR 可能会新建一个对象,而不是将其直接分配给变量。根据 GC 的说法,该对象将是一个准备被收集的死对象。当发生这种情况时,编译器将指示GC尚未运行GC。
这是 msdn 上的一篇博客文章,其中包含更多信息:http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx
编辑:好吧,先生,我对#4 的看法是错误的。看here http://msdn.microsoft.com/en-us/magazine/bb985011.aspx在“安全点”部分。如果我们位于 p/invoke(非托管)代码部分内,则允许它运行,直到它再次返回到托管代码。
然而,根据这篇 MSDN 文章 http://blogs.msdn.com/b/stevenpr/archive/2004/07/26/197254.aspx,如果我们处于 CLR 代码的非托管部分,那么它不被认为是安全的,它们将等到代码返回到托管状态。 (至少我很接近)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)