0

有没有办法根据 xml 的文件大小来估计创建 XpathDocument 实例的内存需求?

XpathDocument xdoc = new XpathDocument(xmlfile);

如果内存下降到非常低的水平,是否有任何方法可以以编程方式停止创建 XpathDocument 的过程?

由于它将整个 xml 加载到内存中,因此如果 xml 太大,最好提前知道。我发现,当我用一个大的 xml 文件创建一个新的 XpathDocument 时,永远不会触发内存不足异常,但是该过程会慢到爬行,只有 5 Mb 的内存仍然可用,并且任务管理器报告它不是回应。当内存为 584 Mb 时,这发生在 266 Mb 的 xml 文件中。我能够在 18 中毫无问题地加载 150 Mb 文件。

加载 xml 后,我想使用 XpathNavigator 和 XpathNodeIterator 进行 xpath 查询。我正在使用.net 2.0,xp sp3。

4

3 回答 3

2

简而言之,不,你不能,除非你在开始估计之前总是有类似的文件来收集静态数据。

由于标记、属性、前缀和命名空间字符串是内部的,它在很大程度上取决于 XML 文件的结构,存储效率如何,与磁盘上的文件相比的比率也取决于使用的编码。

通常,.NET 将任何字符串作为 UTF16 存储在内存中。因此,即使没有显着的结构开销(想象一个只有一个根标记和大量纯文本的 XML 文件),对于 UTF8 源文件(或者 ASCII 或任何其他 8-位编码)使用。所以字符串编码是等式的第一部分。

另一件事是在内存中构建了一个数据结构,以允许有效地遍历文档。通常,节点是通过引用构建和链接在一起的。因此每个节点都会占用一定的内存;由于大多数非值数据都是引用,因此这里使用的内存也很大程度上取决于体系结构(64 位使用单个引用的内存是 32 位系统的两倍)。因此,如果您有一个非常复杂且数据很少的文档(例如,一大堆带有少量文本或属性值的不同标签),您的内存使用量将远高于原始文档大小,这也很大程度上取决于应用程序运行的架构。

如果您的文件很少有很长的标记和属性名称,并且可能使用大量默认命名空间,则使用的内存也可能比磁盘上的文件低得多。

因此,假设一个具有未知编码、合理数量的数据和复杂性的任意 XML 文件将很难得到可靠的估计。但是,如果您的 XML 文件在提到的点上总是相似的,您可以创建一些统计数据来获得一个因素,该因素可以为您的特定平台获得正确的比率。

但是,请注意,在任务管理器中查看“可用内存”或谈论“非常低的内存级别”是非常模糊的量化。虚拟内存、缓存、后台应用程序和服务等将影响有效的原始内存可用性。因此,.NET Framework 无法可靠地猜测它应该允许使用多少内存来保持单个进程的性能,甚至在安全地抛出 OutOfMemoryException 之前。因此,如果您遇到这些异常之一,您通常会超出应用程序可能的恢复点,您不应尝试捕获和处理这些异常。

于 2010-12-30T02:24:07.907 回答
0

您可以简单地检查文件大小并在超过某个上限时退出。

var xmlFileInfo = new FileInfo(xmlfile);
var isTooBig = xmlFileInfo.Length > maximumSize

这不是万无一失的,因为您无法猜测正确的最大尺寸是多少。

于 2010-12-30T01:54:43.490 回答
0

是的,您可以使用 FileInfo 类来做到这一点。

System.IO.FileInfo foo = new System.IO.FileInfo("<your file path as string>"); 
long Size = foo.Length;
于 2010-12-30T01:55:53.393 回答