GC行为和CLR线程劫持
我正在CLR via C#
阅读CLR via C#
一书中关于GC的内容,特别是关于CLR何时想要开始收集的内容。 我知道它必须在收集发生之前挂起线程,但它提到它必须在线程指令指针到达安全点时执行此操作。 在它不在安全点的情况下,它会尝试快速找到一个,并通过hijacking
线程(在线程堆栈中插入一个特殊的函数指针)来实现。 这一切都很好,花花公子,但我认为托管线程默认是安全的?
我最初认为它可能是指非托管线程,但CLR允许非托管线程继续执行,因为任何使用的对象都应该被固定。
那么,托管线程中的 safe point
是什么,GC如何确定它是什么?
编辑:
我认为我不够具体。 根据这篇MSDN文章 ,即使调用Thread.Suspend
,在达到safe point
之前,线程实际上不会被挂起。 它继续进一步说明safe point
是线程执行中可以执行垃圾收集的点。
我想我的问题不清楚。 我意识到一个线程只能在安全点暂停,并且它们必须暂停用于GC,但我似乎无法找到一个明确的答案,关于什么是安全点。 是什么决定了代码中的安全点?
‘安全点’是我们所处的位置:
- 不在陷阱中。
- 最后不在里面
- 不在锁内
-
不在p / invoke’d调用内(在托管代码中)。不在CLR中运行非托管代码。 - 内存树是可步行的。
点#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代码的非托管部分,那么它将被认为是安全的,并且它们将等待代码返回到托管代码。 (至少我很亲密)。
- 用于从char到byte的强制转换的编码
- C#ToString(“MM / dd / yy”)删除前导0
- 如何避免服务定位器模式? 我是不是该?
- xUnit v1测试出现在xUnit GUI(xunit.gui.clr4.exe)中但不出现在VS 2012测试资源管理器中
- 为什么带约束的generics扩展方法不被识别为扩展方法?
- 使用GC.AddMemoryPressure()防止OutOfMemoryException?
- Web浏览器通过窗口电话中的会话cookie进行导航
- 如何读取app.config文件中定义的basicHttpBinding
- 使用cshtml的Visual Studio 2013 Autoformat(CTRL KD)小写问题