关于处理内存使用的大字符串的提示

时间:2010-01-07 14:02:58

标签: c# .net string memory stringbuilder

如何强制收缩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次迭代释放内存。

谢谢。



修改 在阅读What Are Some Good .NET Profilers?后进行一些内存分析后,我发现内存的主要消费者是字符串。

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

我还发现,不是重新创建StringBuilder(20971520),而是更容易内存,更快地执行到StringBuilder.Remove(0, StringBuilder.Length)

在使用大字符串时,是否有任何可以分享以提高性能的提示(其中包含日志的日志文件大约为12.2MB,约为30,000条记录)?

注意:我更改了问题和标签的标题 旧标题:如何强制收缩DataTable和/或列表以释放内存?
旧标签:列出数据表c#.net内存

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

尝试强制垃圾收集器传递:

GC.Collect();

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

GC.WaitForPendingFinalizers();

在GC.Collect()

之后

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

答案 2 :(得分:0)

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

通过执行此操作,您无法控制内存使用情况:这是由CLR垃圾收集器完成的。

答案 3 :(得分:0)

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