MS-Access -> OLEDB -> DataTable -> DataGridView 内存泄漏
MS-Access -> OLEDB -> DataTable -> DataGridView memory leak
我正在为 MS-Access(2016) 数据库编写胖客户端。
我的一个表单在将表单加载到数据网格视图时从数据库中检索数据。问题是关闭此表单后,内存使用量不会回落到空闲状态。应用程序在打开此表单之前使用了大约 20mb,之后是大约 200mb,关闭表单之后几乎保持在 200mb。但如果我再次打开它,它会额外消耗 200mb。
我几乎在任何地方都使用 using 块,尝试显式清空数据表,调用垃圾收集器,但没有任何帮助。
//This is the funcion being called on Form load event
public static DataTable oledb_rs(string command)
{
using (OleDbConnection conn = new OleDbConnection())
{
conn.ConnectionString = Connection.ConnStr();
conn.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = command;
using (OleDbDataAdapter rs = new OleDbDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
rs.Fill(dt);
return dt;
}
}
}
}
}
//The Form load event
using (DataTable megalldt = Connection.oledb_rs("SELECT * FROM Megallapitasok"))
{
dataGridView1.DataSource = megalldt;
}
//The form close event
dataGridView1.Dispose();
this.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.WaitForFullGCComplete();
GC.Collect();
DataGridView.Dispose() 对数据源(及其底层数据)做的不多,它更侧重于处理图形 (GDI+) 对象、可视列、单元格、笔、画笔等。但是它有一个参考。
因此,您需要减少内存的是确保不再有任何内容包含对 DataTable(您创建的实例)的引用。有很多方法可以做到这一点,这取决于你的对象是如何创建的,什么实例引用了什么,它们如何超出范围等等。
最简单的解决办法是关闭第二个表单,然后,dataGridView1将不再被引用(它被第二个表单引用),它的DataSource实例也是如此。然后就可以运行你的GC收集代码了
我正在为 MS-Access(2016) 数据库编写胖客户端。
我的一个表单在将表单加载到数据网格视图时从数据库中检索数据。问题是关闭此表单后,内存使用量不会回落到空闲状态。应用程序在打开此表单之前使用了大约 20mb,之后是大约 200mb,关闭表单之后几乎保持在 200mb。但如果我再次打开它,它会额外消耗 200mb。
我几乎在任何地方都使用 using 块,尝试显式清空数据表,调用垃圾收集器,但没有任何帮助。
//This is the funcion being called on Form load event
public static DataTable oledb_rs(string command)
{
using (OleDbConnection conn = new OleDbConnection())
{
conn.ConnectionString = Connection.ConnStr();
conn.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = command;
using (OleDbDataAdapter rs = new OleDbDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
rs.Fill(dt);
return dt;
}
}
}
}
}
//The Form load event
using (DataTable megalldt = Connection.oledb_rs("SELECT * FROM Megallapitasok"))
{
dataGridView1.DataSource = megalldt;
}
//The form close event
dataGridView1.Dispose();
this.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.WaitForFullGCComplete();
GC.Collect();
DataGridView.Dispose() 对数据源(及其底层数据)做的不多,它更侧重于处理图形 (GDI+) 对象、可视列、单元格、笔、画笔等。但是它有一个参考。
因此,您需要减少内存的是确保不再有任何内容包含对 DataTable(您创建的实例)的引用。有很多方法可以做到这一点,这取决于你的对象是如何创建的,什么实例引用了什么,它们如何超出范围等等。
最简单的解决办法是关闭第二个表单,然后,dataGridView1将不再被引用(它被第二个表单引用),它的DataSource实例也是如此。然后就可以运行你的GC收集代码了