21

好的,各位 ASP.NET 专家:我已经使用反射器来研究 ASP.NET 缓存实现(位于HttpRuntime.Cache和上HttpContext.Current.Cache)在内部使用 aHashtable来保留缓存。

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

在此处输入图像描述

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

=>

托管内存:150 MB

非托管内存:310 MB

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

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


更新

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

在此处输入图像描述

4

1 回答 1

6

# Bytes in all Heaps仅在执行垃圾收集时更新,而以Private Bytes更快的更新速率提供。(我不确定这个数字是从哪里来的、内部的,以及它的更新频率。)

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

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

TL;DR:托管字节的数量应该与私有字节相关,但托管计数器只会在垃圾回收期间更新。


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

于 2013-10-17T17:15:37.633 回答