I've just stumbled across some code that uses the GC.KeepAlive()
method and I am trying to understand how it works. For example, in this code:
Timer timer = new System.Timers.Timer(5000);
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Enabled = true;
GC.KeepAlive(timer);
In this code, my understanding is that a Timer object is created, which spawns a thread that runs every 5 seconds. Next, the GC line is ran. Then the method exits, destroying the timer when garbage collection runs.
The KeepAlive only keeps it alive prior to the call to KeepAlive, which it looks to me is about 0.0000001 seconds and it won't be destroyed there anyway since there is a local reference to it (unless it's destroying it because nothing else happens to the timer object?)
Either way, by the time the 5000 interval is hit the method will have ended ages ago and it's very likely the timer is destroyed. So what's the purpose of that line?
The purpose of the KeepAlive method is to ensure the existence of a reference to an object that is at risk of being prematurely reclaimed by the garbage collector.
When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. It determines which objects are no longer being used by examining the application's roots.
The garbage collection implementation lives in the JVM. Each JVM can implement its own version of garbage collection. However, it should meet the standard JVM specification of working with the objects present in the heap memory, marking or identifying the unreachable objects, and destroying them with compaction.
So what's the purpose of that line?
Nothing. You shouldn't be using it as it's not helping anything. That code was probably written by someone not particularly familiar with how the Timer
class works.
Internally the Timer
class will use entirely different means of ensuring that it is not garbage collected before it should be. See this question for the details.
In this context, there's no reason for that line. The only time it can help is if there is a lot of code between the timer.Enabled
and the call to KeepAlive
, as in:
timer.Enabled = true;
// lots of code here that does
// things that take some time
GC.KeepAlive(timer);
}
That will prevent the garbage collector from collecting the timer before the method ends. Without the call to KeepAlive
, the GC could decide that timer
isn't used any more after Enabled
is set, and it could do an early collection.
If you want a persistent timer, you have to declare it at class scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With