Search code examples
c#winformsdisposesystem.data.datatable

Will DataTable.Dispose() remove it from memory?


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?


Solution

  • 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 calls GC.SuppressFinalize(this) in its Dispose() - skipping this means having to wait for dozens if not hundreds of Gen0 collections before memory is reclaimed.

    Further Reading:

    See this question and the related answer.