使用 dotMemory 了解 w3wp.exe 中的非托管内存

Tom*_*rek 5 asp.net iis memory-management application-pool w3wp

我有一个 ASP.NET MVC Web 应用程序,它在具有大量可用 RAM 的服务器 (Windows Server 2016) 上的自己的应用程序池(.NET 4.7.1 应用程序、64 位、IIS 10)中运行。在启动应用程序并加载第一个网页后,我查看任务管理器,发现 w3wp.exe 进程使用了​​大量内存:

  • w3wp.exe,853 MB 内存(专用工作集)

考虑到它只是一个网络应用程序,我认为这有点太多了。所以我启动 dotMemory 并附加到该进程。我得到这些结果:

点内存截图

此处,它表示已使用的总内存为 1.1 GB(不仅仅是 853 MB),其中非托管内存为 429.5 MB,其余的是堆。

当我得到它的快照时(如屏幕截图所示),它显示总共 1.08 GB,其中 .NET 为 75.06 MB(其余部分是非托管的)。这些数字似乎并没有相加。一个显示 429.5 非托管内存,另一个显示 1 GB 非托管内存。这是否意味着堆在快照中被计为非托管内存?

所有 dotMemory 让我看到的是 63.73 MB 的 .NET 使用内存,在这里我可以看到我拥有多少个类型的对象。


我很想知道剩下的是什么。我无法查看的另一 GB 内存中有什么?是GC还没发布的东西吗?如果是,为什么在 dotMemory 中运行“强制 GC”不会显着减少它?

另外,所有非托管内存从哪里来?我在网上能找到的只是,如果某些位图或 P/Invoke 内容未正确释放,通常会发生非托管内存泄漏。但我的应用程序池从一开始就有这种用法(因此它不会随着时间的推移而累积泄漏),并且它既不处理位图或图像,也不调用本机 DLL 或使用这样做的第三方库。另一种选择可能是它是 ASP.NET 缓存,但它只使用很少,而且我认为在单页加载后它不会有 400 MB。

我过去观察到,如果 IIS 应用程序池有大量可用的可用内存,那么它们可能会非常贪婪,但这似乎相当过多 - 1 GB 与 60 MB。我不明白那里发生了什么事。

我不认为存在内存泄漏,因为我可以让应用程序池运行数周,并且内存不会显着增加。只是当我认为它不应该使用那么多内存时,它使用了相当多的内存。

您能帮我找到一些学习资源或工具来帮助我调查该问题吗?

Ed.*_*ard 1

Gen 0堆大小显示第0代中可以分配的最大字节数;它不指示第 0 代中分配的当前字节数。 http://msdn.microsoft.com/en-us/library/x2tyfybc(v=vs.110).aspx

查看此答案以了解更多详细信息。TL;DR - ASP 由于某种原因为第 0 代创建了巨大的堆。

/sf/answers/1886915061/

  • 感谢您的链接。好的,这就是堆第 0 代的 590 MB。但是 429 MB 的非托管内存呢?有什么办法可以追踪它的来源吗? (2认同)