【问题标题】:Tips on Dealing with Large Strings With Regards to Memory Usage关于内存使用的大字符串处理技巧
【发布时间】:2025-12-04 04:40:01
【问题描述】:

如何强制缩小 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 更快(显然 StringBuilder 的逻辑在附加和设置 MemoEdit.Text 之间是不同的)

我还发现,与重新创建 StringBuilder(20971520) 相比,仅使用 StringBuilder.Remove(0, StringBuilder.Length) 更容易在内存上执行和更快地执行

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

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

【问题讨论】:

    标签: c# .net string memory stringbuilder


    【解决方案1】:

    除非您遇到内存问题,否则不要尝试通过调用垃圾收集器手动释放它。运行时间将为您处理它,并且 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

    【讨论】:

    • 谢谢凯文。如问题中的编辑中所述,是的,该程序在内存使用方面存在问题。嗯,我认为这是个问题。
    【解决方案2】:

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

    GC.Collect();
    

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

    GC.WaitForPendingFinalizers();
    

    在 GC.Collect() 之后


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

    【讨论】:

    • 手动调用 GC 被认为是一种不好的做法。你为什么要这样做?让它完成它的工作。
    • 如果没有性能问题
    • 是的,我会避免调用 GC.Collect - 请参阅此线程 *.com/questions/118633/…
    • 如果您知道自己在做什么,则可能需要采取不良做法。据我所知,这是所提问题的答案。
    • 谢谢 Manu,我会尝试GC.WaitForPendingFinalizers(); 请注意问题的范围已经改变。
    【解决方案3】:

    按照您的示例,坚持使用 DataTable 并删除不必要的行。

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

    【讨论】:

      【解决方案4】:

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

      【讨论】: