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

Ali*_*tad 20 memory asp.net heap caching unmanaged-memory

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

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

在此输入图像描述

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

=>

托管内存:150 MB

非托管内存:310 MB

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

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


UPDATE

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

在此输入图像描述

sis*_*sve 5

# Bytes in all Heaps执行垃圾收集时才更新,而Private Bytes可以以更快的更新速度.(我不确定这个号码来自哪里,内部以及更新频率.)

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

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

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


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