为什么(以及如何)ASP.NET Cache存储在非托管内存中?

时间:2013-10-14 16:49:00

标签: asp.net caching memory heap unmanaged-memory

好的,所有的ASP.NET专家:我用反射器来查看ASP.NET Cache实现(位于HttpRuntime.CacheHttpContext.Current.Cache)内部使用Hashtable来保持缓存。

但是,数据存储在非托管内存中。这很奇怪,因为我无法看到任何数据存储在非托管内存中。但是,编写一个非常简单的Web应用程序,将一大块字节数组插入缓存中,我们可以看到:

enter image description here

  • 私人字节数:460MB
  • 所有堆中的字节数:150MB

=>

托管内存:150 MB

非托管内存:310 MB

所以基本上我多次调用应用程序(每次增加1000x请求,每次将64KB空缓冲区 byte [] 放入缓存中)。因此,增长最快的是私有字节(总内存),而不是所有堆中的字节(托管内存)。但是我希望托管内存与总内存一致增长因为我使用Hashtable将对象添加到托管堆。

你能解释一下这种行为吗?


更新

正如Simon所说,所有堆中的字节值仅在垃圾收集后更改 - 我更改了代码以引发垃圾收集并更新计数器。 Gen 2堆内存的增加与添加的内存量完全相同。但是,非托管内存仍然高得多。在此示例中,堆2仅为96MB,而总内存为231 MB。

enter image description here

1 个答案:

答案 0 :(得分:5)

# Bytes in all Heaps仅在执行垃圾收集时更新,而Private Bytes以更快的更新速率可用。 (我不确定该号码来自何处,内部以及更新频率。)

Private Bytes的数量在17:42:45之后增加。这个金额似乎与大约17:43:10的# Bytes in all Heaps的价值跳跃相匹配。看起来在完成任何垃圾收集之前需要20-25秒并更新# Bytes in all Heaps计数器。

很难弄清楚内存分配如何在屏幕截图中显示的几分钟性能计数器中起作用。 ;)继续运行测试,看看你的期望如何在更长的时间内完成。

TL; DR:托管字节数应与专用字节相关联,但托管计数器只会在垃圾回收期间更新。


来自OP的小记:正如这个回应所说,内存滞后可以通过滞后GC完全解释。非托管内存也上升的事实不是我的问题。谢谢@Simon。