-1

我必须创建一个能够很好地处理读取大文件的 C# 程序。

例如,我有一个 60+ mB 的文件。我将所有内容读入一个闪烁框,我们称之为 sci_log。该程序使用大约 200mB 的内存来实现此功能和其他功能。这仍然是可以接受的(并且少于 Notepad++ 用于打开此文件的内存量)。

我还有另一个闪烁盒,sci_splice。用户输入一个搜索词,程序在文件中搜索(如果文件长度足够小,则搜索 sci_log - 没关系,因为它是双向的)以找到 regexp.match。当它找到匹配项时,它将该行与具有先前匹配项的字符串连接起来,并增加一个临时计数变量。当 count 为 100(或 150 或 200,实际上是任何数字)时,我将输出放入 sci_splice,调用 GC.Collect(),然后重复接下来的 100 行(设置 count = 0,将字符串归零)。

我现在没有代码,因为我是用家用笔记本电脑写的,但问题是它使用了很多内存。200mB 的内存使用量跃升至 1gB 以上,而且看不到尽头。这只发生在具有大量正则表达式匹配的搜索中,因此它与字符串有关。但问题是,GC 不会释放内存吗?还有,为什么涨这么高?为什么它会超过三倍(最坏的情况)是没有意义的。即使所有 200mB 只是内存中的日志,它所做的只是读取每一行并存储它(最坏的情况)。

经过更多测试后,添加行时使用大量内存的 Scintilla 似乎有问题。行的初始读取在几分之一秒内具有高达 850mB 的内存峰值。我想我只需要对输出进行分页。

4

3 回答 3

0

如果您使用 System.String 来存储匹配的行,我建议您尝试用 System.Text.StringBuilder 替换它,看看这是否有任何区别。

于 2010-06-04T08:56:04.090 回答
0

不要调用 GC.Collect。在这种情况下,我认为这并不重要,因为我认为这个内存最终会出现在大对象堆 (LOH) 上。但关键是.Net 比你更了解内存管理。不要管它。

我怀疑您只是按照您描述的方式使用任务管理器来查看它。您至少需要使用 Perfmon。预计你之前没有使用过它,然后去这里做 Tess对它所说的 Get a Memory Dump 所做的事情。不确定您是否已准备好使用 WinDbg,但这可能是您的下一步。

如果没有看到代码,几乎无法知道它发生了什么。问题也可能在 Scintilla 内部,但我会先检查你在做什么。通过运行 perfmon,您至少可以获得更多信息来确定下一步该做什么。

于 2010-06-04T14:32:39.423 回答
0

试试http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile(VS.100).aspx

于 2010-06-04T14:50:04.480 回答