Question

My question is a simple one and is specifically targeted at C# with CLR.

First of all we got code snippet 1:

public void f(SomeClass sc)
{
   anExistingInstance.FieldOfSomeClass = sc;
}

and now code snippet 2:

public void f()
{
  SomeClass sc = new SomeClass();
  anExisitingInstance.FieldOfSomeClass = sc;
}

At code 1, when the method which called f and defined sc is over, I'm guessing that sc gets released and that's why anExisitingInstance.FieldOfSomeClass is no longer valid.

My question is why doesn't the same thing happen at code 2 but with the method f itself? Why when f is done, anExisitingInstance.FieldOfSomeClass still holds a correct value?

Was it helpful?

Solution

The only entity that matters in your example is anExistingInstance. We don't know where it's defined and who holds the reference to it, but this object holds a reference to the SomeClass instance. It doesn't matter who created the SomeClass instance, just that anExistingInstance holds a reference to it. Some other class probably holds a reference to anExistingInstane, and so forth down the chain until you reach a GC root.

As long as your instance of SomeClass is linked back to a GC root, it won't be garbage collected. Once any link in this chain is no longer linked to a GC root (let's say, someone released the reference to anExistingInstance, all the objects referenced by it (which aren't referenced by something else) are eligible for garbage collection.

OTHER TIPS

At code 1, when the method which called f and defined sc is over, I'm guessing that sc gets released and that's why anExisitingInstance.FieldOfSomeClass is no longer valid.

No. When anExistingInstance is out of scope.. then all of its fields are also no longer reachable (unless referenced by another object too). Therefore, sc is only eligible for garbage collection after anExistingInstance is no longer in scope.

If objects were collected when their parent/rooting objects were still in scope.. there would be 10000000 times more NullReferenceExceptions thrown in your code.

My question is why doesn't the same thing happen at code 2 but with the method f itself? Why when f is done, anExisitingInstance.FieldOfSomeClass still holds a correct value?

Its the same. Even though sc is created in that method.. it is now rooted by the anExistingInstance object. Once anExistingInstance is out of scope.. sc is also eligible for garbage collection.

My question is why doesn't the same thing happen at code 2 but with the method f itself?

Because the class that contains the method f hasn't been disposed yet. See, in the first case somebody else created sc so it was able to dispose it--but in the second case you created sc inside the method. It's going to stay in scope while the class that created it is in scope.

Why when f is done, anExisitingInstance.FieldOfSomeClass still holds a correct value?

Object is garbage collected when there are no references to it. In both cases there is an object anExisitingInstance that holds a reference to SomeClass. And will be gc'ed when anExisitingInstance gc'es.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top