Reputation: 4963
I am confused about the effect of calling Dispose()
on a DataTable
. Here is my code to create and dispose a table:
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand("sp_getData", SqlCon);
SqlCommand.CommandType = CommandType.StoredProcedure;
SqlCon.Open();
SqlDataReader dr = cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource = dt;
// Here I dispose the table as I no longer need it and want to free the memory.
dt.Dispose();
But after disposing of the DataTable
I found that it is still showing RowCount = 10k.
Does the Dispose()
method free up the memory and set the object as null
? How can I make it null
or free up the memory occupied by this object?
Upvotes: 19
Views: 54438
Reputation: 23833
DataSet
and DataTable
don't actually have any unmanaged resources, so Dispose()
doesn't do much. The Dispose()
methods in DataSet
and DataTable
exist ONLY as a side effect of inheritance - in other words, they don't actually do anything useful in the finalization.
It turns out that DataSets
, DataViews
, DataTables
suppress finalization in their constructors; this is why calling Dispose()
on them explicitly does nothing.
Presumably, this happens because, as mentioned above, they don't have unmanaged resources; so despite the fact that MarshalByValueComponent
makes allowances for unmanaged resources, these particular implementations don’t have the need and can therefore forgo finalization.
Overview of this Immense Answer:
Without a doubt, Dispose should be called on any Finalizable objects.
DataTables are Finalizable.
Calling Dispose significantly speeds up the reclaiming of memory.
MarshalByValueComponent
callsGC.SuppressFinalize(this)
in itsDispose()
- skipping this means having to wait for dozens if not hundreds ofGen0
collections before memory is reclaimed.
Further Reading:
See this question and the related answer.
Upvotes: 32
Reputation: 393
Try to use Clear() function. It works great for me for disposing.
DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();
Upvotes: 2
Reputation: 64487
Does Dispose() method does not free up the memory & make object as null ??
Dispose
and the disposal pattern is not for reclaiming managed memory or "deleting" managed objects (both things you cannot do and what the Garbage Collector is there for), it is for handling the disposal/release of unmanaged resources or other managed resources that have releasable items, such as SqlConnection
. It certainly won't null
the reference, but may make it unusable from the time of disposal forwards.
How can i make it as null or free up the memory occupied by this object ??
If you want to null the reference, simply dt = null
will work, though this will not give you any benefit as the DataTable
instance is referenced by grdView.DataSource
. Both dt
and grdView.DataSource
will be references to the same underlying DataTable
instance.
I also suspect this is part of a method in which case dt
is method-scoped anyway.
You shouldn't have to worry too much about any of this stuff. I'd be more concerned about having the SqlConnection
outside of a try-finally
/ using
, you are at risk of leaving a connection open there.
I tend to favour calling Dispose
on items that implement IDisposable
for what I think is a very good reason: this is the public contract. The fact of whether calling it does anything or not is an implementation detail and is liable to change at a moments notice.
var dt = new Datatable();
using (var conn = new SqlConnection(""))
using (var comm = new SqlCommand("sp_getData", conn))
{
conn.Open();
using (var reader = comm.ExecuteReader())
{
dt.Load(reader);
}
}
grdView.DataSource = dt;
Upvotes: 9