8

From GC.KeepAlive() on MSDN:

Code this method at the end, not the beginning, of the range of instructions where obj must be available.

Why does it have such non-intuitive behavior?

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
Doug
  • 6,322
  • 3
  • 29
  • 48
  • 4
    `References the specified object, which makes it ineligible for garbage collection from the start of the current routine to the point where this method is called` This definition is quite clear. – Alex F Nov 20 '13 at 14:28
  • @AlexFarber Yes, the definition is quite clear. But what I expect is to know WHY it was designed that way. – Doug Nov 20 '13 at 15:50

1 Answers1

22

Because otherwise technically the JIT and CLI could determine that the value isn't used after that point, and consider the object viable for collection. Heck, the compiler could decide to remove the variable completely and just "pop" it from the stack after the last usage.

Note that GC.KeepAlive doesn't actually do anything. It is an opaque, no-op method. The point is that if you are calling an opaque method with an object as a parameter, that object still needs to be around, i.e. reachable, i.e. non-collectable.

Here's how KeepAlive is implemented (with some uninteresting attributes removed):

[MethodImpl(MethodImplOptions.NoInlining)]
public static void KeepAlive(object obj)
{
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Ok, I see how GC.KeepAlive is just a phony reference. But I am not clear on why the compiler can't decrement the ref-count AFTER the last method called on the object actually returns. See: http://msdn.microsoft.com/en-us/library/system.gc.keepalive(v=vs.80).aspx – jeff7091 Feb 21 '14 at 04:10
  • @jeff7091 you realise there is no ref-count in the CLI, right? Also, the point of `GC.KeepAlive` isn't about methods - a common use is things that have finalizers - for example a timer or tracer that you want to keep running for the duration of something, that you don't want to be collected – Marc Gravell Feb 21 '14 at 08:45