过去两天我一直在关注这个问题,而且我完全没有想法,所以我希望有人能够深入了解到底发生了什么。
简而言之,程序将CSV文件(带有240K行,所以不是很多)加载到DataGridView中,对数据执行大量不同的操作,然后将其转储到Excel文件中以便于查看和显示什么不是。但是,当我迭代DataGridView中的数据时,ram的使用率不断增加。我把代码修剪成最简单的形式,它仍然发生了,我不太明白为什么。
try
{
string conStr = @"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=C:\Downloads;Extensions=csv,txt";
OdbcConnection conn = new OdbcConnection(conStr);
//OdbcDataAdapter da = new OdbcDataAdapter("Select * from bragg2.csv", conn);
OdbcDataAdapter da = new OdbcDataAdapter("Select * from bragg4.csv", conn);
DataTable dt = new DataTable("DudeYa");
da.Fill(dt);
dgvCsvFile.DataSource = dt;
da.Dispose();
conn.Close();
conn.Dispose();
}
catch (Exception e) { }
string sDeviceCon;
for (int i = 0; i < dgvCsvFile.Rows.Count; i++)
{
if (dgvCsvFile.Rows[i].Cells[48].Value != DBNull.Value)
sDeviceCon = (string)dgvCsvFile.Rows[i].Cells[48].Value;
else
sDeviceCon = "";
if ((sDeviceCon == null) || (sDeviceCon == ""))
continue;
}
当我输入for循环时,程序使用230兆。当我完成它,我正在使用3场演出。在这一点上,我甚至没有对数据做任何事情,我只是看着它然后继续前进。
此外,如果我在它之后添加这些行:
dgvCsvFile.DataSource = null;
dgvCsvFile.Rows.Clear();
dgvCsvFile.Columns.Clear();
dgvCsvFile.Dispose();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
RAM使用率保持不变。我无法弄清楚如何在不关闭程序的情况下实际获取内存。
我已经下载了各种内存分析工具,试图弄清楚到底发生了什么:
使用来自Sys Internals的VMMap定期拍摄快照,有些垃圾收集器正在运行的实例正在填满。我以后的每个快照通常都有更多的垃圾收集器运行,所有以前使用的垃圾收集器都使用~260MB的ram。
使用.NET Memory Profiler,我能够获得更详细的信息。据此,我有大约400万个PropertyStore实例,DataGrieViewTextBoxCell和PropertyStore.IntegerEntry []。所有这些似乎都有1个引用,并且在垃圾收集器中是未收集的。
我在x86模式下运行该程序,它导致内存不足异常(不是非常意外)。它将错误抛出DataGridViewTextBoxCell.Clone()内部,而DataGridView中是DataGridViewRow.CloneCells()和DataGridViewRow.Clone()。显然,它正在进行一大堆克隆来访问单元格数据......但为什么它永远不会被清理?有什么可能保留给他们的参考?
我还尝试使用LumenWorks.Framwork.IO中的CachedCsvReader以不同的方式将数据导入DataSource,而不改变功能。
有什么东西我不见了吗?有什么设置我应该在某处改变吗?为什么这些东西都没有被处理掉?
非常感谢任何帮助,谢谢!