如何强制DataGridView释放对绑定数据集的引用?
我们在DataGridView中显示了一个相当大的数据集,并注意到DataGridView关闭后资源没有被释放。如果用户反复查看此报告,则最终会出现内存不足异常。 ANTS Memory Profiler确认尽管dgv.DataSource
设置为空,但DGV仍保持引用。
答案 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()之前先删除它们。