Possible Duplicate:
Resurrection difference in using Object Initializer
I am having a hard time trying to understand how garbage collector works in C# (I'm using 2012, so c# 4.5). Here is my example code:
public class A
{
public int c;
public A(){}
public A(int pC)
{
c = pC;
}
}
public static void Main()
{
// Test 1
var a = new A {c=199};
var aRef = new WeakReference(a);
a = null;
Console.WriteLine(aRef.IsAlive);
GC.Collect();
Console.WriteLine(aRef.IsAlive);
// Console.WriteLine(GC.GetGeneration(aRef.Target)); //output 1
// Test 2
a = new A (200);
aRef = new WeakReference(a);
a = null;
Console.WriteLine(aRef.IsAlive);
GC.Collect();
Console.WriteLine(aRef.IsAlive);
}
Output is True / True / True / False
It seems to me in both tests, the object on the heap has no root before calling GC.Collect. But it happens that in Test 1, the object get through the force gc run, while in Test 2 it doesn't. So, is there something mysterious going on about using initializer? My guess is that there might be "some extra code" when use initializer that would become a strong root for the same object.....
Thanks.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
When using the initializer say
var a = new A {c=199}; --------> 1
compiler includes an extra reference on stack which makes object get through GC .
The statement (1) in the above turns out to be as follows
var temp = new A() ;
temp.c=199;
var a=temp .
I think this temp variable makes this object alive during GC .
Please refer this link
EDIT : As mentioned by TomTom in comments. If debugger is running then GC behaviour will be changed and variabes are kept alive until end of method, not until last use . Please correct me if I,m wrong
Clearly you are running either the Debug build or have a debugger attached. The garbage collector gets lifetime hints from the just-in-time compiler, it generates a table that indicates in what sections of code a local variable can be referenced. The garbage collector walks the stack of the executing method that was interrupted by the GC and checks the execution location against this table. And counts the reference as valid when it finds a match.
If the code was built in the Debug configuration or when a debugger is attached, the jitter modifies this table and lets the variable stay alive until the end of the method body. This makes it a lot easier to debug the code, you can put the local variable in a watch expression and it will produce a result even when you step past the point where the variable is no longer used.
The answer posted by @Imposter is correct, the hidden temporary variable keeps the first instance of A alive. And the garbage collector considers it valid until the end of the method because you are using the debugger. Your second a = null;
assignment allows the second instance to be garbage collected.
What will really happen when you run this code in production is very different. For one, the jitter optimizer will remove the a = null assignments. It knows that those assignments have no useful side-effects so it generates no code for them. Pretty unintuitive, the best way to see this is by taking these steps:
The last option change allows you to keep using the debugger without it affecting the way the jitter generates code. Now the temporary variable will no longer keep the first instance of A referenced, the table generated by the jitter will only mark it as storing a valid reference for the first statement in the method. Run your program and you'll see:
True
False
True
False
With the important new insight that setting a reference to null is not actually necessary, the garbage collector is smart enough to not require you to help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With