2010-01-07 75 views
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次迭代释放一次内存。

谢谢。



编辑: 阅读What Are Some Good .NET Profilers?我发现,记忆的主要消费者是字符串后做一些内存分析后。

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

我也发现而不是重新创建的StringBuilder(20971520),它在记忆更容易和更快地执行,只是StringBuilder.Remove(0, StringBuilder.Length)

有没有,你可以分享任何提示的大字符串(它写出包含日志文件工作时来提高性能大约30 000条记录的日志约为12.2MB)?

注:我已更改问题和标签的标题。
旧标题:如何强制收缩数据表和/或列表以释放内存?
旧标签:列表的DataTable C#.NET存储

回答

1

尝试强制垃圾收集器通:

GC.Collect(); 

如果你想确保,你的代码会继续执行之前的所有对象都确定下来,叫

GC.WaitForPendingFinalizers(); 

右后GC.Collect的()


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

+2

它被认为是不好的做法,手动调用GC。你为什么想这样做?让它做它的工作。 – 2010-01-07 14:07:19

+0

如果没有性能问题是 – 2010-01-07 14:07:19

+1

是的,我会避免调用GC.Collect - 请参阅此线程http://stackoverflow.com/questions/118633/whats-so-wrong-about-using-gc-collect/ – kd7 2010-01-07 14:09:10

0

坚持DataTable并删除不必要的行,如你的例子。

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

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

+0

谢谢凯文。正如在问题的编辑中提到的,是的程序是有内存使用问题。那么,我认为这是一个问题。 – AndrewJacksonZA 2010-01-08 06:49:49