English 中文(简体)
Apparent Memory Leak in DataGridView
原标题:

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.

最佳回答

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:

...
DataGridView dgvQueryResults;
DataTable m_dataTable;
BindingSource m_binder;

public void PopulateView()
{
  ...
  // Bind the data source through and intermediary BindingSource
  m_binder.DataSource = m_dataTable;
  dgvQueryResults.DataSource = m_binder;
  ...
}


/// <summary>
/// Frees lindering resources. Sets data bindings to null and forces 
/// garbage collection.
/// </summary>
private void ResetDataGridView()
{
  dgvQueryResults.DataSource = null;

  if (null != m_binder) m_binder.DataSource = null;
  m_binder = null;

  dataTable = null;

  // Force garbage collection since this thing is a resource hog!
  GC.Collect ();

  m_binder = new BindingSource ();
}

...
问题回答

Do you have any events registered on the DataGridView like OnClick? Make sure you unregister all events, otherwise it will not be garbage collected

Call this to clear DataGridView1:

datagridview1.DataSource = null;
datagridview1.Rows.Clear();
GC.Collect();

How I use it?

I imported data from to DataGridView1 and then studied the content and transferred it to DataGridView2.

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.

Are you closing down the entire Form? or just the DataGridView? I m wondering if this is some caching in the BindingContext. You could try using a new binding-context per DataGridView?

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().





相关问题
Bring window to foreground after Mutex fails

I was wondering if someone can tell me what would be the best way to bring my application to the foreground if a mutex was not able to be created for a new instance. E.g.: Application X is running ...

How to start WinForm app minimized to tray?

I ve successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

Handle DataTable.DataRow cell change event

I have a DataTable that has several DataColumns and DataRow. Now i would like to handle an event when cell of this DataRow is changed. How to do this in c#?

Apparent Memory Leak in DataGridView

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 ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

WPF-XAML window in Winforms Application

I have a Winforms application coded in VS C# 2008 and want to insert a WPF window into the window pane of Winforms application. Could you explain me how this is done.

热门标签