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

Asp.net 使用dotMemory了解w3wp.exe中的非托管内存,asp.net,iis,memory-management,application-pool,w3wp,Asp.net,Iis,Memory Management,Application Pool,W3wp,我有一个ASP.NET MVC web应用程序,它运行在自己的应用程序池(.NET 4.7.1应用程序,64位,IIS 10)中,服务器(Windows server 2016)上有大量可用RAM。启动应用程序并加载第一个网页后,我查看任务管理器,看到w3wp.exe进程使用了大量内存: w3wp.exe,853 MB内存(专用工作集) 考虑到它只是一个web应用程序,我觉得有点太多了。因此,我启动dotMemory并附加到进程。我得到了这些结果: 这里,它表示总使用量为1.1GB(不仅仅

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

  • w3wp.exe,853 MB内存(专用工作集)
考虑到它只是一个web应用程序,我觉得有点太多了。因此,我启动dotMemory并附加到进程。我得到了这些结果:

这里,它表示总使用量为1.1GB(不仅仅是853MB),其中非托管内存为429.5MB,其余为堆

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

所有的dotMemory让我得以窥探的都是63.73MB的.NET使用内存,在那里我可以看到我有多少种类型的对象


我很想知道剩下的是什么在另一个千兆字节的内存中有什么我看不见的?是GC还没有发布的东西吗?如果是,为什么在dotMemory中运行“Force GC”不会显著降低它

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

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

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

你能帮我找到一些资源或工具来研究这个问题吗

Gen 0堆大小显示可在中分配的最大字节数 第0代;它不指示当前的字节数 已在第0代中分配。

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


Debug Diag具有泄漏跟踪功能。@LexLi感谢您的建议。dotMemory实际上也有一些内存泄漏检测,我可能稍后也会查看Debug diag。但正如我在问题中所说的,我不认为这是内存泄漏,因为:(1)我刚开始这个网站,它已经消耗了这么多。(2.)内存使用不会随时间增长(当它运行数周而没有应用程序池重新启动/回收时)。Debug Diag显示本机内存分配,因此应该可以帮助您更好地分析该情况。@LexLi我尝试过,但老实说,找不到如何使用它。但是dotMemory确实不处理非托管内存,所以这可能真的很有帮助。等我有更多的时间再弄清楚,我就得再试一次。您能推荐一些关于如何使用DebugDiag实现这些目的的教程或资源吗?我对内存分析还是很陌生,而且很难使用。。。谷歌可以给你很多好的指南,像这样。谢谢你的链接。好的,这将是堆生成0的590MB。但是429 MB的非托管内存呢?有什么办法能查到那是从哪里来的吗?对不起,我不太清楚。部分可以由.NET保留以备将来使用,另一部分是加载到内存中的.dll等。