【发布时间】:2011-11-23 04:01:41
【问题描述】:
可以创建大量内存密集型对象,然后放弃对它们的引用。例如,我可能想从数据库中下载和操作一些数据,我将进行 100 次单独的下载和处理迭代。我可以声明一个 DataTable 变量,然后为每个查询使用构造函数将其重置为新的 DataTable 对象,从而放弃内存中的旧 DataTable 对象。
DataTable 类具有简单的内置方法来释放它使用的内存,包括 Rows.Clear() 和 .Dispose()。因此,在将变量设置为新的 DataTable 对象之前,我可以在每次迭代结束时执行此操作。或者我可以忘记它,让 CLR 垃圾收集器为我做这件事。垃圾收集器似乎非常有效,因此最终结果应该是相同的。当您不需要它们时,显式处理大量内存对象是“更好”吗(但添加代码来执行此操作)还是仅仅依靠垃圾收集器为您完成所有工作(您受GC算法,但你的代码更小)?
根据要求,这里是说明回收数据表变量示例的代码:
// queryList is list of 100 SELECT queries generated somewhere else.
// Each of them returns a million rows with 10 columns.
List<string> queryList = GetQueries(@"\\someserver\bunch-o-queries.txt");
DataTable workingTable;
using (OdbcConnection con = new OdbcConnection("a connection string")) {
using (OdbcDataAdapter adpt = new OdbcDataAdapter("", con)) {
foreach (string sql in queryList) {
workingTable = new DataTable(); // A new table is created. Previous one is abandoned
adpt.SelectCommand.CommandText = sql;
adpt.Fill(workingTable);
CalcRankingInfo(workingTable);
PushResultsToAnotherDatabase(workingTable);
// Here I could call workingTable.Dispose() or workingTable.Rows.Clear()
// or I could do nothing and hope the garbage collector cleans up my
// enormous DataTable automatically.
}
}
}
【问题讨论】:
-
您的问题(标题中的那个)的答案是NO。显示您的代码以获得更详细的答案。如果你不依赖 .NET GC,那你肯定做错了什么。
-
这个问题取决于“明确处理大量内存对象”。这在 .NET 中是不可能的,只有垃圾收集器才能做到这一点。 IDisposable 与内存无关。
-
@Hans Passant,为
IDisposable has nothing to do with memory+1。 -
@jmh_gr,如果没有具体的例子,我们就无法具有建设性。
-
IDisposable 有助于尽早释放非托管资源。内存是一种非不受管理的资源。