I read some informations about Garbage Collection (how it's works etc.). I tried understand how it's working doing my examples but I think I have problem. I know Garbage Collector runs when:
is not enough memory,
you call GC.Collect().
This is my code:
public partial class Form1 : Form
{
public Testing _d;
public Boolean _first = false;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (!_first)
{
_d = new Testing();
int test = _d.DoSomething("example");
}
}
private void button2_Click(object sender, EventArgs e)
{
_first = true;
}
private void button3_Click(object sender, EventArgs e)
{
//if (_first)
//{
// _d = null;
//}
GC.Collect();
}
}
public class Testing
{
private ASCIIEncoding _ascii;
private bool _disposed = false;
public Testing()
{
_ascii = new ASCIIEncoding();
}
public int DoSomething(string message)
{
return _ascii.GetByteCount(message);
}
}
When I click button1 I'm creating new object Testing. _d is reference to this new object. I'm dumping memory using JetBrains dotTrace Memory and see this new object exists. After click button2 I'm setting boolean _first to true in order to _d became unreachable. At this point I thought when I run GC.Collect() GC will 'clear' this object from stack, but I see it's still exists. I misunderstood about GC work? or I'm doing this wrong?
It's working when I set _d = null;
Clicking Button2 does not make
_d
unreachable.The GC only collects objects that are not referenced by a rooted object.
As long as your form has a reference to
_d
, it won't be collected.This is because
_d
is a reference to theTesting
instance which you set and never clear._d
still points to the object on the heap and will maintain this reference until you clear it (by calling (_d = null
).Unreachable doesn't mean that
_d
cannot be assigned to something else, but rather the object sitting in the heap has no chance of being called again (as no references exist in the code)Therefore the GC cannot possibly clear it, as it may be still used later on in your code.
If you were to call GC.Collect(), all objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected by GC. Check this
You have misunderstood how the GC is determining an object to be reachable: Any object that is referenced by a variable in the current local scope, any static variables and any instance variables of objects that are reachable are themselves "reachable" - look at it as a graph with the fore-mentioned variables as "roots" of the graph.
In your example
_d
is still holding a reference to your object so it is still reachable and won't be garbage collected.Setting
first=false
does not make the_d
instance unreachable in terms of the the GC. Logically you may never use it again but it is still referenced in theForm1
class.If someone were to set
first=true
again, would you not expect the object to still be usable?