【问题标题】:XmlDocument caching memory usageXmlDocument 缓存内存使用情况
【发布时间】:2010-04-06 10:48:04
【问题描述】:

我们发现在使用 XmlDocument 的 .NET Web 应用程序中内存使用率非常高。 一个小的 (~5MB) XML 文档被加载到一个 XmlDocument 对象中并存储在 HttpContext.Cache 中,以便在每次加载页面时进行查询和 XSLT 转换。 XML 会定期在磁盘上进行修改,因此缓存依赖于文件。

这样的应用程序似乎使用了数百兆的 RAM。

我已经尝试在每次请求开始时请求垃圾收集,这可以使 RAM 使用率大大降低,但我无法想象这是一个好的做法。

对于我们如何实现相同的目标但 RAM 使用率更低,是否有人有任何建议?

【问题讨论】:

  • 我怀疑问题中的“似乎正在使用”。如果您使用虚拟(尽可能接近零 MB)XML 文档,您的内存使用量会相应下降吗?内存是 XML 文档还是 XSLT 转换?
  • 如果不管它,内存使用量会继续增长还是随着时间的推移稳定?
  • Binary Worrier - 我说“出现”是因为使用了几种技术来观察内存使用量的增加,我无法给你一个确切的数字,但它肯定会上升。我相信它是 XML 文档而不是转换。 AnthonyWJones - 在页面加载之间空闲时它会稳定下来,即使流量持续不断,它也会随着时间的推移而趋于平稳,即它不会永远继续增长。
  • 在这种情况下,这可能很正常,如果您的内存没有其他需求,.NET 可能不必太在意快速释放内存。

标签: .net xml caching xmldocument


【解决方案1】:

我的两分钱。 . .

如果内存使用基于 XML 文档的大小呈指数增长,我会担心。例如1mb XML 文件内存稳定为 10mb,2mb 变平为 30mb,等等。

另外,考虑 XML 文件的成本,与其说是字节大小,不如说是每个节点的成本。如果您的 5mb XML 文档有两个数据节点,那么文档的内存表示不会比 5mb 大很多(实际上它可能要小得多,考虑到 XML 中的二进制数据将是它的两倍记忆)。

*如果您的 XML 文档是 utf-8,并且您有两个大文本节点,那么内存中的表示可能是 10mb(文本可以存储在 .net 字符串中,它们是 Unicode,并且将是标准英语 UTF-8 文本宽度的两倍)。

如果 XML 文档由许多离散的字符串值组成,那么每个节点都是一个对象,每个节点名称都是一个对象,每个节点值都是一个对象。因此,假设引用是 4 个字节,那么(至少)每个节点多出 12 个字节。

现在,假设您有很多节点,并且假设您的节点名称+值的平均长度是 20 个字符,那么 5mb 文件的引用开销是 3mb,加上 utf-8 到 Unicode 的可能额外 100%转换,它需要 5MB + 5mb + 3mb(至少)= 13mb(至少)的 ram 来存储 5mb XML 文件。 . .这还不包括内存对齐丢失的字节数,或者用于存储每个字符串对象大小的额外字节**

还要考虑到,因为您正在缓存 XML 文档,所有这些对象都会立即成为第 2 代可收集对象,这基本上意味着 GC 将非常懒惰地走动那相当大的堆以查看它的内容可以收藏。

请参阅Rico Mariani's When to call GC.Collect() 了解不仅可以调用 GC Collect 的情况,而且在需要调用它的情况下。

希望这会有所帮助,如果我向合唱团宣讲内存大小的问题,请见谅。

* 我不知道这是否真的是这样,但如果不是,我会感到惊讶。
** 我假设.net 字符串在之前/之后存储字符串的大小字符串的实际字符,这可以显着增加内存中的表示,每个节点额外增加 4-8 个字节,每 20 个字节的节点名称/值产生 20 个字节的成本。这有效地增加了与存储数据大小相匹配的开销。

【讨论】:

    【解决方案2】:

    由于积极的 GC 可以清理所有内容,因此您应该寻找可能不会处理实现 IDisposable 的对象的地方。也许您需要使用 XSL 转换查看您的代码,以确保其中使用的对象得到正确处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 2013-02-10
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 2012-05-30
      相关资源
      最近更新 更多