I have a ASP.NET FRAMEWORK 4.0 website that has a memory leak. To find it I have installed ANTS Memory Profiler.
This is what I do :
- Host website in IIS7
- Start Ants Memory Profiler 8.1
- Set the we are profiling a IIS website and state the URL to this webpage (built in release)
- Start test and let the webpage startup (a lot of caching so about 1 min)
- Take Memory Snapshot when first page is loaded and stable
- Reload first page A LOT and see the memory raise from 110 MB (Private Bytes/Working Set -Private) to 270 MB
- Visit a lot of pages on the webpage and see it raise to 360 MB
- Push it some more and no more raise is done
- Take Memory Snapshot and click Class list (check Classes with source)
This will show classes that are still kept for example
sites_mypage_default_asx - 10 320 bytes and 10 live instances
usercontrols_common_pagehead_ascx - 928 bytes and 4 live instances
and so on
I belive/hope that these are the classes that will be cleaned by the GC
But this is not where the large foot print is, I have to uncheck the Classes with source to get the really large one. For example(sorted on Live size(byte)
string - 1 890 292 bytes
RuntimeMethodInfo - 990 976 bytes
RuntimePropertyInfo - 604 136 bytes
Hastable+bucket[] - 413 712 bytes
and so on.
The problem is that there is not much I can do about these, when opening Instance relation graph I will only see System. classes and there is no information about where thay are hold in my website.
When the classes with source was checked I however found a big memory leak that could be fixed(this was before the above run).
But I do not know how to take the next step? Why is my website still taking up 350 MB? 350 MB with data is a lot of data and I canĀ“t see that I cache this much data!?
What should be my next step?
It not must have be a memory leak, just the memory pressure is not enough for the Garbage Collector to make more comprehensive job. To fully investigate this issue and check if it is a real memory leak you should make a long-running load test of your web page with average traffic. You can use Visual Studio Ultimate Load Testing if you are luck to have it or open source LoadUI project. During this test observe Performance Counters:
# Bytes in all Heaps
and allGen # heap size
,Process : Working Set
andProcess : Private bytes
After few hours of such test you will clearly see a trend of memory consumption. It might be that it will be released periodically if some threshold is exceeded. But if a memory consumption will grow all the time, you will have a more probable assumption of the memory leak. Then take a full memory dump of
w3wp
process at the end of memory leak and try to investigate it further.As I am a big fan of WinDbg (it is faster, more detailed and cheaper than any GUI-based commercial tool), I suggest you to use it. Use it with Psscor2 or Psscor4 extension (depending version used by you application). After setting up the debugging environment (installing WinDbg and copying to its folder Psscor files), create a dump of the process. You can do it easily for example with help of Procdump tool:
Then load dump using File -> Open Crush Dump option. Load appropriate version of Psscor:
Then execute command to download symbols from Microsoft servers (if needed), make sure that you have an internet connection:
And from now you should have access to plenty very interestings command (look for
!help
to list them). To see memory usage per type:Which will result in a long list of types and their memory usage sorted ascending:
To see overall memory usage (
iu
means that also unrooted objects will be included):This information for sure will lead you to some conclusions, but further investigation is obviously possible so do not hesitate to ask.