Reputation: 143
In C#, I call GC.Collect()
in both Form1_Load
and click event
Question is GC.Collect()
seems did nothing in Form_load
But works in click event. Why ?
GC.Collect()
first time inForm1_Load
GC.Collect()
second time inclick event
With visual studio 2015 diagnosis tool
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataTable dt;
private void Form1_Load(object sender, EventArgs e)
{
dt = new DataTable();
dt.Columns.Add("1", typeof(int));
dt.Columns.Add("2", typeof(int));
dt.Columns.Add("3", typeof(int));
for (int i = 0; i < 1000000; i++)
{
DataRow dr = dt.NewRow();
dr[0] = 10;
dr[1] = 1000;
dr[2] = 10000;
dt.Rows.Add(dr);
}
//gc first time
dt = null;
GC.Collect();
}
private void button1_Click(object sender, EventArgs e)
{
//gc sec time
dt = null;
GC.Collect();
}
}
Upvotes: 0
Views: 181
Reputation: 43886
To call GC.Collect
is the worst thing you can do (as in about 100% of the time).
GC.Collect
checks the reference count of the objects in your application's memory. Since you set dt
to null, there should be no more reference to that DataTable
instance. Ok, so the garbage collection "collects" it. But that only means that it puts it on the finalizer queue. You did not call dt.Dispose
which would have called GC.SuppressFinalize(this)
to inform the gc that this object does not need to be put on the finalizer queue.
By enqueueing this object for finalization, there is a new reference to the DataTable
and the object is moved up one generation. The result is that the garbage collection will keep this memory even longer.
By calling GC.Collect
a second time in your button handler you make things even worse. Because again, all still referenced objects are moved up one generation and kept even longer.
You should simply dispose the DataTable
by calling dt.Dispose
or enclosing it in a using statement:
private void Form1_Load(object sender, EventArgs e)
{
using (DataTable dt = new DataTable())
{
dt.Columns.Add("1", typeof(int));
dt.Columns.Add("2", typeof(int));
dt.Columns.Add("3", typeof(int));
//... your code
}
}
And even if you do that, please don't call GC.Collect
. Let the garbage collection do it's job as it always knows best how to do it. It will free unused memory if it needs to.
See Understanding Garbage Collection in .NET or this Microsoft article for further information.
Upvotes: 2