我很少来这里寻求帮助,但这让我发疯:我正在读取一个包含任意数量项目的 xml 文件,每个项目都有一个 b64 编码文件(以及一些随附的元数据)。XmlDocument
最初我只是把整个文件读入一个XmlDocument
. 所以我重写了代码来代替使用XmlTextReader
,如果问题是程序被发送了一个带有大量大小合理的附件的 xml 文件,这很好用......但仍然存在一个大问题,这就是我转向你的地方:
如果我的 xml 阅读器位于 File 元素上,该元素包含一个巨大的值(例如,500MB),我调用reader.ReadElementContentAsString()
,我现在有一个占用 500MB 的字符串(或者可能是 OutOfMemoryException)。在这两种情况下,我想做的只是写入日志,“那个文件附件太大了,我们将忽略它并继续前进”,然后转到下一个文件。但似乎我刚刚尝试读取的字符串并没有被垃圾收集,所以实际发生的是字符串占用了所有 RAM,并且之后它尝试读取的每个其他文件也会引发 OutOfMemoryException,即使大多数的文件将非常小。
回想一下:此时,我正在将元素的值读入本地字符串,所以我预计它会立即有资格进行垃圾收集(因此最迟在程序尝试阅读下一项并发现它没有可用的内存)。但是我已经尝试了一切,以防万一:将字符串设置为null,调用显式GC.Collect()
......没有骰子,任务管理器指示GC只收集了大约40k,它刚刚请求存储字符串的~500MB,我仍然会出现内存不足异常尝试读取其他内容。
似乎没有任何方法可以在XmlTextReader
不读取该元素的情况下知道 xml 元素中包含的值的长度,所以我想我一直在阅读字符串......我错过了什么,或者真的没有如何从 xml 文件中读取一个巨大的值而不完全破坏你的程序之后做任何事情的能力?我要疯了。
我读过一些关于 C# 的 GC 和 LOH 的内容,但我读到的任何内容都不会向我表明这会发生......
如果您需要任何进一步的信息,请告诉我,谢谢!
编辑:我确实意识到该进程是作为 32 位进程运行的,这意味着它比应有的更多地缺乏内存。解决了这个问题,这不再是一个问题,但它仍然是我想修复的行为。(需要更多和/或更大的文件才能达到抛出 OutOfMemoryException 的点,但是一旦抛出,我似乎仍然无法及时回收该内存。)