DataGridView中的明显内存泄漏

时间:2009-11-09 16:22:13

标签: c# .net winforms memory-leaks

如何强制DataGridView释放对绑定数据集的引用?

我们在DataGridView中显示了一个相当大的数据集,并注意到DataGridView关闭后资源没有被释放。如果用户反复查看此报告,则最终会出现内存不足异常。 ANTS Memory Profiler确认尽管dgv.DataSource设置为空,但DGV仍保持引用。

6 个答案:

答案 0 :(得分:3)

您是否在DataGridView上注册了任何事件,如OnClick?确保取消注册所有事件,否则不会进行垃圾回收

答案 1 :(得分:1)

您是否关闭了整个Form?或只是DataGridView?我想知道这是否是BindingContext中的一些缓存。您可以尝试使用每个DataGridView的新绑定上下文?

也;像往常一样,仔细检查事件等 - 特别是任何使用捕获的变量,因为这是添加依赖项的一种微妙方式(注意捕获范围意味着如果你有复杂的匿名方法/ lambda,你捕获的范围可能比你想象的要多)。 / p>

您可能需要放入探查器或windbg以查找剩余的参考。

答案 2 :(得分:1)

强制DataGridView释放资源的技巧是通过中间对象BindingSource进行绑定。

代码看起来像这样:

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

...

答案 3 :(得分:1)

调用此方法清除DataGridView1

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

我如何使用它?

我将数据导入DataGridView1,然后研究了内容并将其转移到DataGridView2

所以它使用了2.4GB的内存然后,在调用Clear后,它降到正常 - 对我来说是128KB。

答案 4 :(得分:1)

我们在datagridviews中看到过这种行为,这些行为的数据源包含很多图像,其中datagridview被重复加载。将datagridview的DataSource设置为null并在每次加载之前对数据源和GC.Collect执行Dispose似乎可以处理泄漏。

答案 5 :(得分:0)

您不应将DataGridView设置为null。您应该在DataGridView上调用dispose,以允许它正确地清理自己,而不是向GC添加更多工作来处理它。

此外,如果您对DataGridView有任何根提式引用,它将永远不会被处理(即使您调用Dispose())。 GC认为它还活着。你应该检查它的任何有根引用 - 即事件处理程序,静态引用等,并在调用Dispose()之前先删除它们。