C#垃圾回收

问题描述:

我有一个我写的商业应用程序,它通过查找特定Excel文件的目录结构有效地递归并存储它们的地址。然后循环遍历这些文件并通过为每个文件创建一个DocumentParser对象来解析它们,一次只执行一个,而不是异步。该软件似乎非常稳定,以至于企业希望通过一个包含10000个以上相关Excel文件的大型目录来运行它。C#垃圾回收

我的问题是,当我每次创建一个新的DocumentParser对象时,GC将足够有效地丢弃每个对象,当它们超出范围时,即当该Excel工作表已被解析或存在一种方式我可以监视这一点,并在必要时手动做一个GC?我以前从来不需要处理如此大量的数据,通常一次只能测试最多40-50个Excel文件。

谢谢。

+0

请注意:如果你在Fx4上查看EnumerateFiles而不是GetFiles – 2011-05-05 12:14:15

我会离开GC到其业务。对于GC来说,10,000个对象并不是很有用。 GC工作的成本很可能远低于Excel工作的成本。所以将你的设计复杂化为调整GC的东西并不值得。如果最终有太多的文件需要处理,以至于应用程序无法及时完成,那很可能是Excel处理的速度让你感到担忧。

但是可能相关的一个注释:如果DocumentParser在使用Excel文件工作时使用非托管内存,则可以使用GC.Add/RemoveMemoryPressure向GC指示打开文件时的实际添加成本。如果您没有自己编写DocumentParser,作者可能已经在执行此操作。

这里的问题是,你可能有一个管理对象,在100个字节的顺序,当它的Excel工作当中分配了大量的非托管内存的有成本的。 GC将无法知道这一点,所以这些方法有助于通知GC存在比它意识到的更多的内存压力。这可能会改变它在决定采集时的方式/行为,这可能会导致应用程序维持较低的内存占用量。如果应用程序的内存使用量随着时间的推移而逐渐消失,那么您可能会开始看到从垃圾收集长度和可能在机器上分页的一些缓慢下降(取决于您拥有多少内存)。您需要密切关注其内存使用情况,以确保内存在处理时不会泄漏内存 - 内存分析器可能对此有所帮助。

您不需要手动调用GC,除非您持有一些非常大的资源,但情况并非如此。 GC会随着每次通话调整自己,如果你手动调用它,你只会破坏它的内部分析数据。

顺便说一句,GC不仅可以收集东西,当它超出范围时,也可以在最后一次使用后收集东西(即,它仍然在范围内但变量不再使用)。

GC是一个非常复杂的软件。而GC至少是唯一知道何时需要垃圾回收的人。所以我的建议是让GC独立。

此外:GC将处理这些质量对象。也许你会认识到性能下降。如果这是一个问题,你可以尝试优化你的代码。但不过早。

+1

+1不成熟的优化是许多恶魔的根源! – 2011-05-05 11:10:59

是和否 - GC在需要时足以有效释放,但通常无法确定。

有一种方法可以强制GC采集,但在生产代码中通常被认为是不好的做法,因为在不需要时强制执行堆栈遍历的效果会更差,直到GC决定使用一点额外内存它需要释放资源来分配更多的对象。

+0

很久以前我在Slashdot上写过这篇文章:http://developers.slashdot.org/comments.pl?sid=363691&cid=21389893 – 2011-05-05 11:17:19