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

4
我有一个运行在自己的应用程序池中的ASP.NET MVC Web应用程序(.NET 4.7.1应用程序,64位,IIS 10),运行在一个具有大量空闲内存的服务器上(Windows Server 2016)。在我启动应用程序并加载第一个Web页面后,我查看任务管理器,发现w3wp.exe进程占用了相当多的内存:
  • w3wp.exe, 853 MB 内存(私有工作集)
考虑到这只是一个Web应用程序,我认为这有点太多了。所以我启动了dotMemory并附加到该进程。我得到了以下结果:

dotMemory screenshot

这里,它说总使用量为1.1 GB(不仅仅是853 MB),其中非托管内存为429.5 MB,其余的是堆。
当我获取快照时(如屏幕截图所示),它显示总共1.08 GB,其中.NET为75.06 MB(其余为非托管)。这些数字似乎不符合。一个说429.5非托管内存,另一个则显示近1GB的非托管内存。这是否意味着堆被计算为快照中的非托管内存?
所有dotMemory让我窥视的只有63.73 MB的.NET使用内存,我可以看到我有多少个对象以及它们属于哪些类型。
我很想了解其他内容。那另外一个GB的内存里是什么?这是GC尚未释放的东西吗?如果是,为什么在dotMemory中运行“Force GC”不能显著减少它?
此外,非托管内存从何而来?我能在网上找到的都是非托管内存泄漏通常发生在某些位图或P/Invoke的东西没有正确释放时。但我的应用程序池一开始就有这种使用情况(因此不是随着时间累积的泄漏),它既没有处理位图或图像,也没有调用本地DLL或使用第三方库。另一个选项可能是它是ASP.NET缓存,但只使用了很少,我不认为它会在加载单个页面后就有400 MB的缓存。
我曾经观察到,在IIS应用程序池具有大量可用内存的情况下,它们可能会非常贪婪,但这似乎过分了——1 GB对比60 MB。我不明白发生了什么。
我不认为有内存泄漏,因为我可以让应用程序池运行数周,内存并没有显著增加。只是当我认为它不应该使用那么多内存时,它使用了相当多的内存。
你能帮我找一些研究资源或工具来帮助我调查这个问题吗?

Debug Diag具有泄漏跟踪功能。 - Lex Li
@LexLi 感谢您的建议。dotMemory实际上也有一些内存泄漏检测功能,我可能稍后会查看Debug diag。但正如我在问题中所述,我认为这不是内存泄漏的原因是:(1.)我刚刚启动了该站点,它已经消耗了这么多内存。(2.)当它运行数周且没有应用程序池重启/回收时,内存使用量不会增长。 - Tom Pažourek
调试诊断显示本机内存分配,因此应该更好地帮助您分析情况。 - Lex Li
@LexLi 我试了一下,说实话我真的找不到如何使用它。但是确实,dotMemory无法处理非托管内存,所以这可能真的有所帮助。等我有更多时间去弄清楚它的用法时,我会再试一次的。你能推荐一些关于如何使用DebugDiag进行这些目的的教程或资源吗?我还是很新手,而且使用起来相当困难... - Tom Pažourek
1
这篇文章介绍了如何使用Debug Diag 1.1调试本地内存泄漏问题。Google可以提供大量类似的好指南,比如这个。 - Lex Li
1个回答

1

2
谢谢提供链接。好的,那就是堆生成0的590 MB。但是429 MB的非托管内存呢?有没有办法追踪它来自哪里? - Tom Pažourek
1
抱歉,我不确定。部分可能是由.NET为未来需要保留的,另一部分是加载到内存中的.dll文件等。 - Ed Pavlov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接