4

我需要解析一个 xml 文件,它实际上是一个非常大的树结构的图像,所以我使用 XmlReader 类来“动态”填充树。每个节点仅通过 ReadSubtree() 函数从其父节点传递它期望的 xml 块。这样做的好处是不必担心节点何时消耗了它的所有子节点。但现在我想知道这是否真的是一个好主意,因为可能有数千个节点,并且在阅读 .NET 源文件时,我发现每次调用 ReadSubtree 都会创建几个(可能更多)新对象,并且没有缓存可重用对象(我见过)。

也许 ReadSubtree() 没有被认为被大量使用,或者我只是什么都不担心,我只需要在解析文件后调用 GC.Collect() ......

希望有人可以对此有所了解。

提前致谢。

更新:

感谢您提供的精彩而有见地的答案。

我深入研究了 .NET 源代码,发现它比我最初想象的要复杂。我终于放弃了在这种情况下调用这个函数的想法。正如 Stefan 指出的那样,xml 阅读器永远不会传递给外人,我可以信任解析 xml 流的代码(由我自己编写),所以我宁愿强制每个节点对它们的数据量负责从流中窃取而不是使用最终不那么薄的 ReadSubtree() 函数来节省几行代码。

4

2 回答 2

10

ReadSubTree() 为您提供了一个包装原始 XmlReader 的 XmlReader。这种新阅读器在消费者看来是一个完整的文档。如果您传递子树的代码认为它正在获取独立的 xml 文档,这可能很重要。例如,新 Reader 的 Depth 属性从 0 开始。它是一个非常薄的包装器,因此与直接使用原始 XmlReader 相比,您不会使用更多资源,在您给出的示例中,它是很可能您并没有真正从子树阅读器中获得太多。

在您的情况下,最大的优势是子树阅读器不会意外读取子树。由于子树阅读器不是很昂贵,因此这种安全性可能就足够了,尽管当您需要子树看起来像一个文档或者您不相信代码只能读取它自己的子树时,它通常会更有帮助。

正如 Will 所说,你永远不想调用 GC.Collect()。它永远不会提高性能。

于 2008-09-22T11:58:22.527 回答
2

假设所有对象都是在普通托管堆上创建的,而不是大型对象堆(即小于 85k),这里应该没有问题,这正是 GC 旨在处理的问题。

我建议也没有必要在进程结束时调用 GC.Collect,因为在几乎所有情况下,允许 GC 自行安排收集允许它以最佳方式工作(有关详细信息,请参阅此博客文章GC 的解释比我能解释得更好)。

于 2008-09-22T12:05:48.627 回答