How do you force a DataGridView to release its reference to a bound DataSet?
We have a rather large dataset being displayed in a DataGridView and noticed that resources were not being freed after the DataGridView was closed. If the user repeatedly views this report they eventually get an out of memory exception. ANTS Memory Profiler confirmed that the DGV is holding a reference despite dgv.DataSource
being set to null.
Call this to clear
DataGridView1
:How I use it?
I imported data from to
DataGridView1
and then studied the content and transferred it toDataGridView2
.So it used 2.4GB of memory and then, after calling
Clear
, it dropped to normal - for me to 128KB.We've seen this behavior with datagridviews that have a datasource that contains a lot of images where the datagridview gets loaded repeatedly. Setting the DataSource for the datagridview to null and doing a Dispose on the datasource and a GC.Collect prior to each load seems to handle the leak.
The trick to forcing the DataGridView to release resources is to do the binding through the intermediary object
BindingSource
.The code then looks something like this:
Are you closing down the entire
Form
? or just theDataGridView
? I'm wondering if this is some caching in theBindingContext
. You could try using a new binding-context perDataGridView
?Also; as always, double check events etc - in particular any using captured variables, as that is a subtle way of adding a dependency (note the capture scopes mean you might be capturing more than you think if you have complex anonymous methods / lambdas).
You might need to drop into profilers or windbg to find the remaining reference.
You shouldn't set the DataGridView to null. You should call dispose on the DataGridView instead to allow it to properly clean itself up instead of adding more work to the GC to handle it.
Also, if you have any rooted references to the DataGridView, it will never be disposed (even if you call Dispose()). The GC thinks it's still alive. You should check for any rooted references to it - i.e. event handlers, static reference, etc. and remove those first before calling Dispose().
Do you have any events registered on the DataGridView like OnClick? Make sure you unregister all events, otherwise it will not be garbage collected