4

I have an ASP.NET MVC web application that's running in its own app pool (.NET 4.7.1 app, 64bit, IIS 10) on a server (Windows Server 2016) with lots of free RAM. Just after I start the application and load a first web page, I look at the task manager, and see the w3wp.exe process using quite a lot of memory:

  • w3wp.exe, 853 MB Memory (private working set)

I think it's a bit too much considering it's just one web app. So I launch dotMemory and attach to the process. I get those results:

dotMemory screenshot

Here, it says the total used is 1.1 GB (not just 853 MB), from which unmanaged memory is 429.5 MB, the rest is the heap.

When I get a snapshot of that (as shown in the screenshot), it says 1.08 GB total, out of which .NET is 75.06 MB (rest is unmanaged). Those numbers don't seem to add up. One says 429.5 unmanaged memory, the other shows like 1 GB of unmanaged memory. Does it mean that the heaps are counted as unmanaged memory in the snapshot?

All the dotMemory lets me peek in are the 63.73 MB of .NET used memory, where I can see how many objects of which types I have.


I'm curious to understand what's the rest of that. What's in the other gigabyte of memory I cannot peek in? Is it stuff that GC hasn't released yet? If yes, why doesn't running "Force GC" in dotMemory decrease it significantly?

Also, where does all the unmanaged memory come from? All I could find online was that unmanaged memory leaks usually happen if some bitmaps or P/Invoke stuff isn't released correctly. But my app pool has this usage from the start (so it's not leaks accumulated over time), and it's neither dealing with bitmaps or images nor calling native DLLs or using third-party libraries that do. The other option might be that it's ASP.NET cache, but it's only used very little, and I don't think that it would have 400 MB in it just after a single page load.

I've observed in the past that IIS app pools can be quite greedy if they've got a lot of free memory available, but this seems quite excessive - 1 GB vs 60 MB. I don't understand what's going on there.

I don't think there are memory leaks, as I can keep the app pool running for weeks, and the memory doesn't increase significantly. It's just that it uses quite a lot of memory when I think it shouldn't use that much.

Can you please help me find some resources to study or tools to help me investigate the issue?

Tom Pažourek
  • 9,582
  • 8
  • 66
  • 107
  • Debug Diag has leak tracking feature. – Lex Li Jan 31 '18 at 11:19
  • @LexLi Thanks for the suggestion. dotMemory actually have some memory leak detection as well, I might check out Debug diag later too. But as I stated in the question, I don't think it's a memory leak because: (1.) I just started the site and it's already consuming this much. (2.) The memory usage doesn't grow over time (when it's running for weeks without app pool restart/recycle). – Tom Pažourek Jan 31 '18 at 16:00
  • Debug Diag shows native memory allocation so should assist you better analyse the case. – Lex Li Jan 31 '18 at 16:21
  • @LexLi I tried it out, and couldn't really find how to use it, to be honest. But it's true that dotMemory doesn't deal with unmanaged memory, so this could really help. I'll have to try again later once I get more time to figure it out. Can you recommend some tutorial or a resources about how to use DebugDiag for these purposes? I'm still quite new to memory profiling, and it's quite difficult to use... – Tom Pažourek Jan 31 '18 at 22:08
  • 1
    https://blogs.msdn.microsoft.com/tess/2010/01/14/debugging-native-memory-leaks-with-debug-diag-1-1/ Google can give you tons of good guides, like this. – Lex Li Jan 31 '18 at 22:46

1 Answers1

1

Gen 0 heap size displays the maximum bytes that can be allocated in generation 0; it does not indicate the current number of bytes allocated in generation 0. http://msdn.microsoft.com/en-us/library/x2tyfybc(v=vs.110).aspx

Look at this answer for more details. TL;DR - ASP creates huge heap for generation 0 for some reason.

https://stackoverflow.com/a/26955929/779822

Ed Pavlov
  • 2,353
  • 2
  • 19
  • 25
  • 2
    Thanks for the link. Ok, that would be the 590 MB of the heap generation 0. But what about the 429 MB of unmanaged memory? Any way to track down where that come from? – Tom Pažourek Jan 31 '18 at 15:58
  • 1
    Sorry, I don't know exactly. Part can be just reserved by .NET for future needs, another part are .dlls loaded into memory etc. – Ed Pavlov Jan 31 '18 at 20:03