【问题标题】:Can I force a .NET XmlDocument instance to release the memory it's holding sooner?我可以强制 .NET XmlDocument 实例更快地释放它持有的内存吗?
【发布时间】:2012-08-11 06:13:30
【问题描述】:

我有一个 Mono for Android 应用程序,它使用 .NET XmlDocument 类读取 XML 文件。每个文档大约 180K。

解析每个文档并创建自己的内部数据结构后,我没有留下对 XmlDocument 实例的引用,因此它可以进行垃圾回收。

但是,问题是,在该收集发生之前需要 5-6 秒,如果我在 5-6 秒内加载多个文档,我的应用程序会崩溃到操作系统,并且不会打印任何错误消息,也不会引发异常,等等。它只是说线程 12 退出了(我没有创建任何额外的线程,所以我也不明白为什么它是线程 12——XmlDocument 的线程?)。

如果我加载文档 1,然后等待 5 秒,然后加载文档 2,等待 5 秒然后加载文档 3,等等,那么一切正常。

在这种情况下,在 5 秒的等待期间,我可以看到 GC 启动了几次,并在 4-5 个周期内总共释放了大约 1MB 的内存(一些标记为 EXPLICIT,一些标记为 CONCURRENT)。

按照我找到的一篇文章的建议完成后,我还尝试添加对 xmlDocument.RemoveAll() 的调用。之后我还添加了对 GC.Collect() 的调用。它有一点帮助,但它仍然崩溃,只是频率有所降低。

知道如何增加可用内存或让 XmlDocument 表现得更好吗?

【问题讨论】:

  • 您是否可以不处理您正在从中加载文档的流或 XmlReader,或者您正在保存它的流或 XmlWriter,从而导致将内容添加到终结器队列中,并且从而导致更多的 GC 提升?
  • 如果一切都失败了,请尝试使用 XDocument。这是一个更好的 API,只是在这种情况下它可能会更好地工作。
  • 也许重用 XmlDocument 实例并简单地重新加载它们?
  • Jon Hanna:我正在使用将文件路径字符串作为参数的构造函数,所以我无法控制流。
  • John Saunders:这可能会有所帮助,尽管即使在 XmlDocument 上调用 RemoveAll() 然后执行 GC.Collect() 也没有多大帮助,所以也许没有。我认为那里仍然存在一些缺陷。可能是 C# XmlDocument 与 Java GC 交互的方式。

标签: c# garbage-collection xamarin.android xmldocument xamarin


【解决方案1】:

这与其说是一个答案,不如说是一个替代方案,但我使用 XmlTextReader 重写了我的 XML 解析代码,问题不再出现。

当然 XmlTextReader 不需要将整个 XML 文件加载到内存中,这对内存使用有很大帮助。

我现在可以一个接一个地快速加载多个文件,而不会崩溃。

XmlTextReader API 需要做更多的工作才能做到正确,但现在看起来很稳定。

【讨论】:

    猜你喜欢
    • 2020-09-23
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 2015-06-26
    • 1970-01-01
    • 2017-06-11
    • 2018-11-24
    相关资源
    最近更新 更多