[ What happen to a variable in the end of a block in managed code ]

After the end of a block

{
}

What happens to the variable that are in the block?

{
    int a;
    a=2;
    int b = 3;
}

//What happened now???

and what happen after this block

{
    int a=2;
    int b = 3;
}
GC.Collect();

Is it clear? If the tags I have selected is wrong please edit it or if you can edit my question to be clear please edit it.

Answer 1


The reference variables within the block will be go out of scope. When marked by the garbage collection they will remain marked as they no longer have any references. Since you don't have any reference variables, the GC will not get involved.

At a certain point the garbage collector will run and decide whether the memory used by reference variables can be cleared. This depends on what generation they are in, so they might not get removed immediately.

Calling GC.Collect(); simply forces the GC to run, though collection is not certain. This, for most applications, is not needed.

Answer 2


At the end of a block, all variables declared inside just 'go out of scope'.

Most likely they are popped of the stack but the details are op to the optimizer(s).

And since your example variables are all ints (ValueTypes) they have nothing to do with Garbage Collection.

If we change the last example to:

{
  int a=2;
  var b = new StringBuilder();
  ...
}
GC.Collect();

Then the memory for the StringBuilder will be collected in GC.Collect(). Note that a normal program never needs to call GC.Collect().

Answer 3


At the end of a block the varialbles that were declared inside the block go out of scope. If they are value types (like int) they simply get popped off the stack. If they are reference types (like most other objects, e.g. StringBuilder) then they will no longer be referenced (unless you passed it to something outside the block that is still in scope) by anything and the garbage collector will get it sometime later.

If you have objects that access scarce resources, like the various Stream based classes (or anything that implements IDisposable) then you should put that in a using statement like this:

using (Stream s = GetStream())
{
    // Do something with the stream.
}

At the end of the using block then the Dispose method is called and any resources are freed up (such as file handlers, database connections, large chunks of memory, etc.)

In general you do not need to understand when exactly the garbage collector will run or free up memory. It was one of the hardest things for me to understand way back when I moved from C++ to .NET in 2002 simply because I was so used to calling delete on any object I created on the heap.

You no longer have to worry about any of this. Even if you forget to call dispose the garbage collector will get to it eventually (although you probably don't want to keep that file handle longer than necessary, hence IDisposable)