为什么最后调用GC.KeepAlive,而不是在开头?

Dou*_*oug 7 .net c# garbage-collection

来自GC.KeepAlive()MSDN:

obj必须可用的指令范围的最后(而不是开头)编码此方法.

为什么会出现这种非直观的行为?

Mar*_*ell 19

因为从技术上讲,JIT和CLI可以确定在该点之后不使用该值,并认为该对象可用于收集.哎呀,编译器可以决定完全删除变量,并在上次使用后从堆栈中"弹出"它.

请注意,GC.KeepAlive 实际上并没有做任何事情.这是一种不透明的无操作方法.关键是如果您使用对象作为参数调用opaque方法,则该对象仍然需要在周围,即可达,即不可收集.

这是如何KeepAlive实现的(删除了一些不感兴趣的属性):

[MethodImpl(MethodImplOptions.NoInlining)]
public static void KeepAlive(object obj)
{
}
Run Code Online (Sandbox Code Playgroud)