I am eager to know what happens to a object in .NET when it falls out of scope. Something like this:
class A
{
ClassB myObjectB = new ClassB();
}
//what happens to object at this point here?
What happens in the memory? Does GC get called when it falls out of scope and loose it reference in the heap?
Following from pst's comment, a better example might be this:
In this example,
myObjectB
is a local variable rather than a field. So, what happens when the local variable goes out of scope? Nothing! Scope has nothing to do with object lifetime in C#.What really happens is that the JIT compiler decides to release the object at some point. That can be before the end of the variable's scope, if the variable is not going to be used in the rest of the method. Once the object is no longer referenced, as other answers have also mentioned, it becomes eligible for collection by the GC. It is not actually collected until the GC runs (actually, until the GC collects the generation in which the object is living).
As pst implied, a field is a poor example because it will always be reachable whenever its containing object is reachable, so the separation between scope and object lifetime is even greater:
I find "falling out of scope" to be a much more C++-specific way of thinking of things, where at the end of a given scope an object with automatic storage is freed and has its destructor called.
In the C# world, there's no "falling out of scope". Variables (read: names) exist in a certain scope, and that's it. The GC really has no concern for this; an object can be collected before the end of its name's scope even exits, or long afterwards depending on what references it and when the GC decides a collection is necessary.
The two concepts should then be divorced and reasoned about separately. Scoping is all about names, whereas garbage collection cares only about the reachability of objects. When an object is no longer reachable from one of the known roots, it will be scheduled for collection.
If there's nothing referencing the object, it gets eventually collected by GC. The thing is, you can't predict WHEN exactly it will happen. You just know, it will happen.
Generally speaking, Garbage Collection happens at 3 distinct generations (0, 1, or 2). When each of these is collected depends on how much resources are needed by the OS.
A call to GC.Collect() will collect all of the available resources but it is possible to define which generation of resources to collect.
No - the GC doesn't get called at this point.
What happens is that the object is left in memory, but is now "unrooted" - basically, there are no references to that object from any other object. As such, the object is now eligible for garbage collection.
At some point in the future, the GC will run. When this happens, the unrooted object will now be eligible for garbage collection. Depending on which generation holds the object, it may or may not be cleaned at that point. Eventually, if the program continues executing and if memory pressure causes the appropriate generation to be collected, the memory for that object will be reclaimed.
There is no definite point in time when this will happen (unless you explicitly call
GC.Collect
, which is a bad idea). However, with managed code, you don't really need to worry about when this will happen. Just assume that it will happen when and if appropriate for your specific application.