0

如何强制缩小 DataTable 和/或 List 以便有效释放内存?我目前在循环的每次迭代中都从 DataSet 中删除已处理的行,但我不确定是否正在释放内存。

for (int i = m_TotalNumberOfLocalRows - 1; i >= 0; i--)
{
   dr = dt.Rows[i];
   // Do stuff
   dt.Rows.Remove(dr);
}

如果这不能缩小 DataTable 在内存中的占用空间,我可以使用 List。我只使用 DataTable 作为 DataRows 的存储,我可以使用任何内存不足的集合或存储机制,并且能够在每 x 次迭代中释放内存。

谢谢你。



编辑:在阅读了哪些是好的 .NET Profilers 之后进行了一些内存分析之后?我发现内存的主要消费者是字符串。

在这个过程中我们做了大量的用户输出,内存消耗在大约 170MB-230MB 之间循环,峰值在 300MB 左右。我正在使用初始大小为 20971520 的 StringBuilder 来保存正在发生的事情的输出/日志,在处理完记录总数的百分之一后,我将 DevExpress MemoEdit 控件的 Text 属性设置为 StringBuilder.ToString ()。我发现这种方法比将 StringBuilder.ToString() 附加到 MemoEdit.Text 更快(显然 StringBuilder 的逻辑在附加和设置 MemoEdit.Text 之间是不同的)

我还发现,与其重新创建 StringBuilder(20971520) 相比,它在内存上更容易,执行起来也更快StringBuilder.Remove(0, StringBuilder.Length)

在处理大字符串时,您是否可以分享任何技巧来提高性能(它写出的包含日志的日志文件大约为 12.2MB,大约有 30 000 条记录)?

注意:我已经更改了问题的标题和标签。
旧标题:如何强制缩小数据表和/或列表以释放内存?
老标签: list datatable c# .net memory

4

4 回答 4

4

除非您遇到内存问题,否则不要尝试通过调用垃圾收集器手动释放它。运行时间将为您处理它,并且 99% 的时间比您尝试猜测最佳时间的时间更有效率。

您必须记住的是,当您调用 GC.Collect() 时,它会针对垃圾收集的所有级别运行并“整理”所有需要释放的对象。您很可能会花费处理器时间等来处理当时不需要完成的事情。

如果你绝对有命令是GC.Collect()

http://msdn.microsoft.com/en-us/library/xe0c2357.aspx

http://www.developer.com/net/csharp/article.php/3343191/C-Tip-Forcing-Garbage-Collection-in-NET.htm

于 2010-01-07T14:08:25.963 回答
1

尝试强制垃圾收集器通过:

GC.Collect();

如果您想确保在继续执行代码之前完成所有对象,请调用

GC.WaitForPendingFinalizers();

在 GC.Collect() 之后


编辑:正如人们在下面的评论中提到的,直接调用垃圾收集器被广泛认为是一种不好的做法。尽管如此,这将实现释放已删除行的未使用内存的目标。

于 2010-01-07T14:06:05.440 回答
0

坚持 DataTable 并删除不必要的行,如您的示例所示。

通过这样做,您无法控制内存使用:这是由 CLR 垃圾收集器完成的。

于 2010-01-07T14:06:32.570 回答
0

您是否明确需要直接管理它?垃圾收集器会为您管理这些。

于 2010-01-07T14:07:42.630 回答