Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
I have put together a quick and dirty debug diag script for troubleshooting .net memory leaks. (attached to this post)
The reason I put it together was mainly to show how you can create your own debug diag scripts but feel free to use it to troubleshoot memory leaks, knowing that it does string parsing on the output so it is a bit prone to errors if sos changes output formats.
NOTE: This script will only work on .NET 2.0 x86 memory dumps
Mourad recently published a whitepaper on debug diag that talks about how to use it for various scenarios and he also explains how to create some basic scripts and I used this as my starting point.
My script loads up sos from the framework directory and goes through the following steps.
1. Print .NET Framework Version
2. Print information on the GC (Garbage Collector) heaps and report the amount of memory used for .NET objects
3. Print and categorize the 40 most memory consuming object types (so that you can spot which object types you might be leaking or using a lot of)
4. Print the finalizequeue so that you can see what objects on the heap have finalizers to verify that they are neccessary. It also reports potential blocking of the finalizer including the finalizer stack so that you can see if/why your finalizer thread is blocked.
5. Print objects on the large object heap
6. Determine and report the size of the cache for each asp.net application in the process
7. Report the number of active sessions in the process
8. Check if the process was in a GC when the dump was collected as this may invalidate heap/object information
How to use the script
1. Install debug diag 1.1 from https://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en
2. Unzip the attached file and put the DotNetMemoryAnalysis.asp file in the C:\Program Files (x86)\DebugDiag\Scripts directory (or your debugdiag/scripts directory if you installed it somewhere else)
This will add a new analysis script to the Advanced Analysis tab in debug diag:
2. Generate a memory dump when memory usage is high. With debug diag you can do this by going into the processes tab, right-click on the process and select “Create Full Userdump”
3. In the Tools/Options & Settings menu, set the “Symbol Search Path For Analysis” to SRV*c:\websymbols*https://msdl.microsoft.com/download/symbols
4. In the Advanced Analysis tab, select Add Data Files, add your memory dump, select the DotNetMemoryAnalysis.asp script and click Start Analysis (note that some of the steps may take a while depending on the size of the dump). If you get an InStr exception that means that you are either trying to debug a 64 bit dump or the sos version in your framework directory is not matching up to the framework version of the dump (i.e. the proper mscordacwks symbol could not be found)
Once the analysis is done you will be presented with a mhtm file containing the report.
Sample report:
Here is a sample report generated for a dump taken for Lab 3 where the finalizer is blocked because of some bad code in the destructor for the Link object.
For this example we can see already from the analysis summary that something is fishy with the finalizer, and in the finalizer section we can also see the finalizer stack.
Scrolling down to the 40 most memory consuming object types we find a lot of Link/Link_aspx and System.Web.UI… objects, so in this case the report is pretty much straight on. In other cases it might be a bit less obvious but hopefully the suggested articles help narrow it down.
|
|
|
Have fun,
Tess
Comments
Anonymous
May 11, 2009
PingBack from http://asp-net-hosting.simplynetdev.com/debug-diag-script-for-troubleshooting-net-20-memory-leaks/Anonymous
May 11, 2009
Thank you for submitting this cool story - Trackback from DotNetShoutoutAnonymous
May 12, 2009
I have put together a quick and dirty debug diag script for troubleshooting .net memory leaks. (attachedAnonymous
May 13, 2009
If you are looking to follow this series, be sure to subscribe to my RSS feed at http://feeds.jasongaylordAnonymous
May 13, 2009
If you are looking to follow this series, be sure to subscribe to my RSS feed at http://feeds.jasongaylord.com/JasonNGaylordAnonymous
May 17, 2009
Web The Evolution of a Website Design Twitter from ASP.NET IIS 7 Tip # 10 You can generate machine keysAnonymous
May 17, 2009
WebTheEvolutionofaWebsiteDesignTwitterfromASP.NETIIS7Tip#10Youcangenera...Anonymous
May 22, 2009
When the .NET Framework was first released, many developers believed the introduction of the garbageAnonymous
May 26, 2009
Tess, Good Morning ... Really Cool Stuff Couple of suggestion:
- Can you show the process size
- Showing whether Debug is set to true
- Lastly showing the no. in MB instead of bytes (bytes looks scary at first look) i.e Cache Size: 1397928 Bytes Cache Size: 1.3 MB Thanks Jas
Anonymous
May 26, 2009
When the .NET Framework was first released, many developers believed the introduction of the garbageAnonymous
May 26, 2009
When the .NET Framework was first released, many developers believed the introduction of the garbageAnonymous
May 27, 2009
Hi Tess, This is really great and very usefull. I second jaskis thoughts on shosing few more details(Debug Status, Process Size and if possible showing the size in MB's) Thanks, SojeshAnonymous
May 27, 2009
Tess you are already my hero, but I would like to third the suggestion to add Debug flag information to the script. JITOptimizerDisabled; IsJITTrackingEnabled;web.config and machine.config text checks <3Anonymous
June 17, 2009
The comment has been removedAnonymous
June 17, 2009
Nitin, It's hard to say if a given number is "ok" or not, it completely depends on what you do in in the app. If you are looking to find out if you have a native memory leak, you should really look at if the native part is growing or not (processprivate bytes - .net clr memory#Bytes in all heaps in perfmon). In your case here you have the same difference whether your process is 712 MB or 1.27 GB and you can clearly see that the increase in memory = increase in .net memory, so here i would definitely say, just concentrate on the .net stuff.Anonymous
June 24, 2009
The comment has been removedAnonymous
June 24, 2009
not hard at all once debug diag x64 goes public. It's just a matter of tweaking a few things with the formatting of the outputAnonymous
August 31, 2009
Thanks Tess! This script looks really helpful. I'll give it a spin on some memory dumps soon. I've been using the built in tool for a couple years but this looks like it offers more details and insight.Anonymous
September 07, 2009
Hi Tess. This script worked great, but I am still puzzled about my memory problem. The Virtual memory size of my appPool is 1.3gb and the dump made from debugdiag is 840mb. Still your script reports: GC Heap Usage:5422712 Heap 0 size: 1147572 Heap 1 size: 961668 Heap 2 size: 927148 Heap 3 size: 822328 Heap 4 size: 320712 Heap 5 size: 210356 Heap 6 size: 299548 Heap 7 size: 733380 Finalizer queue: SyncBlocks to be cleaned up: 0 MTA Interfaces to be released: 0 STA Interfaces to be released: 0 and there are no objects on the LOH. Do you have any idea what can cause this? I occationally get OutOfMemoryException on this appPool, so I do have a problem somewhere :)Anonymous
September 07, 2009
If this is all you have in terms of managed memory your memory usage is either mostly native or in dynamic assemblies. Try running debug diag with leaktracking and run it through the normal analysis. (you can even run it through the normal memory analysis without leaktracking just to get an idea of where your memory is going)Anonymous
December 14, 2009
Hi Tess, Now that the x64 version of debugdiag is released, have you created an x64 version of this? Thanks!Anonymous
December 14, 2009
I haven't, but I may do so later. If someone else wants to do it, please feel free to post a link to the 64 bit version here. Should be very similar to the 32-bit version with small changes for parsing 64bit values. Most of it should actually work as is.Anonymous
March 12, 2010
The comment has been removedAnonymous
March 27, 2010
Hi Tess, Thanks so much for your blog, I've learned so much about debugging from your labs and videos. It's great how you start from scratch and walkthrough various scenarios. Regarding this debugdiag script, I'm trying to run it on my dump but it seems to be stuck on "Determining the size of cache, this might take awhile" for at least 20min so far. Is this normal?Anonymous
March 28, 2010
D, Depending on the size of the dump, yes, it might take a long while since it has to enumerate everything referenced from the cache...Anonymous
March 29, 2010
I left it running over night and it never finished. I'll try it again I guess.Anonymous
February 07, 2011
Hi Tess , Is there any script will work on .NET 1.0/1.1 x86 memory dumps? Thanks MS