XmlDocument缓存内存使用情况

时间:2010-04-06 10:48:04

标签: .net xml caching xmldocument

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

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

我已经尝试过在每个请求启动时请求垃圾收集,这使RAM的使用率保持在较低水平,但我无法想象这是一个好习惯。

有没有人对我们如何实现相同目标但RAM使用率较低有任何建议?

2 个答案:

答案 0 :(得分:5)

我的两分钱。 。

如果内存使用是基于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字节节点名/值的字节成本。这有效地增加了与存储数据大小相匹配的开销。

答案 1 :(得分:1)

由于积极的GCing可以清理你应该寻找你可能没有处置实现IDisposable的对象的地方。也许您需要使用XSL Transform查看代码,以确保在那里使用的对象得到妥善处理。