问题描述
可以创建大量内存密集型对象,然后放弃对它们的引用.例如,我可能想从数据库中下载和操作一些数据,我将进行 100 次单独的下载和处理迭代.我可以声明一个 DataTable 变量,然后为每个查询使用构造函数将其重置为新的 DataTable 对象,从而放弃内存中的旧 DataTable 对象.
It's possible to create lots of memory-intensive objects and then abandon references to them. For example, I might want to download and operate on some data from a database, and I will do 100 separate download and processing iterations. I could declare a DataTable variable once, and for each query reset it to a new DataTable object using a constructor, abondoning the old DataTable object in memory.
DataTable 类具有简单的内置方法来释放它使用的内存,包括 Rows.Clear() 和 .Dispose().因此,在将变量设置为新的 DataTable 对象之前,我可以在每次迭代结束时执行此操作.或者我可以忘记它,让 CLR 垃圾收集器为我做这件事.垃圾收集器似乎非常有效,因此最终结果应该是相同的.当您不需要它们时,显式处理内存重的对象是更好"吗(但添加代码来执行此操作)还是仅依靠垃圾收集器为您完成所有工作(您受制于GC算法,但你的代码更小)?
The DataTable class has easy built-in ways to release the memory it uses, including Rows.Clear() and .Dispose(). So I could do this at the end of every iteration before setting the variable to a new DataTable object. OR I could forget about it and just let the CLR garbage collector do this for me. The garbage collector seems to be pretty effective so the end result should be the same either way. Is it "better" to explicitly dispose of memory-heavy objects when you don't need them, (but add code to do this) or just depend on the garbage collector to do all the work for you (you are at the mercy of the GC algorithm, but your code is smaller)?
根据要求,这里是说明回收数据表变量示例的代码:
Upon request, here is code illustrating the recycled DataTable variable example:
// queryList is list of 100 SELECT queries generated somewhere else.
// Each of them returns a million rows with 10 columns.
List<string> queryList = GetQueries(@"\someserverunch-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.
}
}
}
推荐答案
好的,是时候把事情弄清楚了(因为我原来的帖子有点泥泞).
Ok, time to clear things up a bit (since my original post was a little muddy).
IDisposable 与内存管理无关.IDisposable
允许对象清理它可能持有的任何本机资源.如果一个对象实现了 IDisposable
,你应该确保使用 using
块或在完成后调用 Dispose()
.
IDisposable has nothing to do with Memory Management. IDisposable
allows an object to clean up any native resources it might be holding on to. If an object implements IDisposable
, you should be sure to either use a using
block or call Dispose()
when you're finished with it.
至于定义内存密集型对象然后丢失对它们的引用,这就是垃圾收集器的工作方式.那是一件好事.让它发生,让垃圾收集器完成它的工作.
As for defining memory-intensive objects and then losing the references to them, that's how the Garbage Collector works. It's a good thing. Let it happen and let the Garbage Collector do its job.
...所以,回答您的问题,不.依赖 .NET 垃圾收集器并不是一个坏习惯.事实上恰恰相反.
...so, to answer your question, No. It is not a bad practice to depend on the .NET Garbage Collector. Quite the opposite in fact.
这篇关于依赖 .NET 自动垃圾收集器是不好的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!