Ofir Hadad
Ofir Hadad

Reputation: 1900

Does GC.KeepAlive clean OnTimeEvent Variables and classes types?

I have a Timer function that I'm calling it from the Application_Start in the global.asax

this is the class:

public class AlertTimer
{
    public AlertTimer()
    {
        //
        // TODO: Add constructor logic here
        //
    }
    static System.Timers.Timer aTimer = new System.Timers.Timer();
    public static void Start()
    {
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 30000;
        aTimer.Enabled = true;
        GC.KeepAlive(aTimer);
    }
    public static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        PresenceService ps = new PresenceService();
        ps.GetAbsenceContacts(); //takes 10 seconds
    }
}

Now , My question is if this class type PresenceService ps = new PresenceService(); is getting clean after the timer done with the run, or the GC is keeping it in the memory and start a new one every time that the OnTimedEvent run.

thanks!

conclusion: To remove GC from the code. Tnx!

Upvotes: 1

Views: 295

Answers (2)

Brian Gideon
Brian Gideon

Reputation: 48949

The ps instance will be eligible for garbage collection when OnTimedEvent ends.1 Well, that is assuming, of course, that PresenceService does not somehow root its own reference (via a static variable, etc.).

Also, GC.KeepAlive is not needed in this case. The reason is that aTimer is static so its lifetime is already tied to the application domain. In other words, aTimer is not eligible for collection at any point in the Start method because it is semi-permanently rooted by the static variable.

GC.KeepAlive is used in scenarios where the GC gets overly aggressive. When you compile the application with the release configuration and run it outside of the debugger the GC will mark object instances eligible for collection even before they go out of scope. For example, ps could be collected even before GetAbsenceContracts completes! GC.KeepAlive basically turns that optimization off. You typically see it used in unmanaged interop scenarios where you pass an object reference to an unmanaged API. Because the GC does not know anything about what is going on in the unmanaged realm it may mistakenly think the reference is no longer used and collect it prematurely.


1Technically, this is not exactly correct. The instance is eligible for collection when the GC thinks it is no longer used. It really has little to do with whether or not it is still in scope.

Upvotes: 2

Jason Whitehorn
Jason Whitehorn

Reputation: 13685

Now , My question is if this class type PresenceService ps = new PresenceService(); is getting clean after the timer done with the run, or the GC is keeping it in the memory and start a new one every time that the OnTimedEvent run.

Yes.

The instance of PresenceService will leave scope, and therefore be subject to garbage collection. However, since GC is mostly indeterministic, it is still in memory until such time as it's reclaimed. Therefore, on object's that do things and have life cycles (like timers for example) it's good to call some type of "shutdown" method.

However, the larger question I have is why you're running a timer in a web app and why you feel the need to call any methods directly on the Garbage collector. This is generally a sign that something is off about your application.

Upvotes: 5

Related Questions