views:

84

answers:

5

Let's say we have the following code in a class:

//class code
TextBox t = new TextBox();
ListBox l = new ListBox();

We have then two possible situations:

In the first, we declare qem1 as a class variable(or attribute, as they call it in the Java World):

//class variable
QuickEntryMediator qem1 = new QuickEntryMediator(t,l);

In the second, we declare it inside a method:

//method variable
QuickEntryMediator qem2 = new QuickEntryMediator(t,l);

So, I'd say qem1 would never be Garbage Collected before the class goes out of scope while in the qem2 might be Garbage Collected at any time after the method in which it resides dies. Is this true?

I am looking for answers for both C#(.net) and Java, as am I am not sure both GC's work in the same fashion!

Thanks

+1  A: 

Both C# and Java will do this the same. The GC will check for roots which are defined as any static variable (class variable) or any variable referenced directly or indirectly from a thread stack.

An object instantiated within a method will go out of scope when that method (or block) ends unless it is returned or saved outside of that scope - in a class or object variable.

By the way a class never goes out of scope for the duration of the process it is loaded in unless, in Java, the ClassLoader is collected and in C#, the assembly is unloaded. If you are talking about an object variable (non-static), then all the references for that object go "out of scope" when the object itself does.

Also, this is all up to the GC so the objects may not be collected immediately.

Kevin Brock
+1  A: 

I both Java and C#, the data associated with a variable is garbage collected some time after the last reference to the variable goes out of scope. The specific moment of the effective garbage collection after the variable becomes eligible for GC is typically not defined in the language(s) specification.

It is difficult to answer your question because it is unsure whether the qem1 and qem2 variables where the QuickEntryMediator object is initially allocated are local variables or if they are instance variables (or even globally static); the snippets show do not show this.

Furthermore the l and t variables themselves have no bearing on when/if the QuickEntryMediator object(s) will be deleted, they merely complicate the picture. Your intent in showing these however, may be in trying to infer from the QuickEntryMediator objects lifetime the lifetime of the TextBox/ListBox themselves, in case QuickEntryMediator makes references to them.

mjv
It appears that `qem2` would be local scope because he says "...we declare it inside a method." The `//class variable` comment is a little more difficult to understand - I would interpret that to mean it was also `static` but it may be an object variable (since he also says "attribute").
Kevin Brock
A: 

We have to distinguish between the Java specification and Oracle's popular implementation HotSpot. The Java standard does not guarantee the time of garbage collection. The JVM may not do this garbage collection until the program closes, and it may do so in any order.

Yuvi Masory
A: 

Garbage collection in .NET is non-deterministic, meaning you have no way of knowing when it could happen. It will happen sometime after the object is no longer in scope or referenced.

Anthony Pegram
+1  A: 

Note that in C# (and I believe in Java as well) an object is eligible for collection the moment is no longer strongly referenced (directly or indirectly), and this could happen before the reference variable goes 'out of scope', as long as the reference is no longer used. Objects can be collected while still in scope, as long as the runtime can determine that they are no longer necessary (ie., the program is done with any references to the object).

So qem2 could be eligible for collection long before the method it's defined in 'dies' *by which I think you mean returns), but the depends entirely on how qem2 is used.

With the following simple C# code, the mutex created at the start of Main() might be garbage collected at any point after its creation - it might not live until the end of the scope of Main() because nothing ever references it after it's created.

static void Main(string[] args)
{
    bool createdMutex;

    System.Threading.Mutex mutex = new
    System.Threading.Mutex(true,"myAppMutex",out createdMutex);

    if (!createdMutex)
    {
        MessageBox.Show( "an instance of myApp is already running", "myApp running...");
        return;
    }

    Application.Run();
}

See the following for more information.

Note that at least in .NET, running under a debugger will keep objects alive until the end of scope, so if you're going to test this out make sure you do it outside of a debugging situation.

Michael Burr