Reputation: 6446
I have an application in .net that gets more and more memory. I've got some analyzes from a team member about the most common and most heavy instances that my application allocates.
The problem is that I don't know what to do next. The source code is huge!! and I need best practice how to capture the problematic functions/lines of code.
p.s - I've tried using visual studio's ".net memory allocation (sampling)" feature but it always failed to create the report. (guess it could be another question).
Upvotes: 2
Views: 351
Reputation: 5355
If I'm not mistaken it looks like your teammate is already using WinDbg with a managed extension (maybe SOS?) and have called !dumpheap -stat. Get a copy of his memory dump file, open in it in WinDbg, and load SOS.
The first step is to drill down to the particular types. In your case, it looks like you have an unusually large allocation for strings (around 84MB). So try looking at the list of strings by running:
!dumpheap -type System.String
It will output a long list of string instances. The output will look something like this:
Address MT Size Gen
0x412d0030 0x79b94638 812 1 System.String XXXX
0x422d0030 0x79b94638 812 1 System.String XXXX
0x432d0030 0x79b94638 812 1 System.String XXXX
This command will probably run for a few minutes because you have a lot of string instances but try to observe the output while its running. If you notice that a lot of the instances have the same size, that's usually a good sign that you are not properly releasing your resources. Any of those instances is a good candidate for the next step. If at the end of the list you also see strings with large sizes, these are good candidates for the next step as well.
The next step is to check which objects are referencing a particular string instance and is preventing it from being garbage-collected. You can do this by using an address from the dumpheap output above and then calling:
!gcroot 0x432d0030
This will output something like this:
173866dc(System.Web.UI.WebControls.ListItemCollection)->
173866ec(System.Collections.ArrayList)->
173894b8(System.Object[])->
17386d0c(System.Web.UI.WebControls.ListItem)->
17386ce8(System.String)
You can read that from bottom to top. So in this example, the String is held by ListItem which in turn is held by an array of Objects. At this point, solving your problem becomes more of an art. Start from the bottom of that chain (including String) and for each line going up, check if you can justify storing that object in memory. If not, then you should find a way to release that resource and have it garbage collected. This step will most likely require you to look and analyse the code for each class.
Tip: Since you also have an unusually large number of instances for System.Action, there is a good chance that you are subscribing to an event/multicast delegate and you forgot to unsubscribe afterwards.
Upvotes: 0
Reputation: 62504
Visual Studio Profiler
perfectly suit your requirements, it able to show a hot path in the call stack. You've to learn how to work with profiler so if you can't generate Visual Studio profiler report and was not able to investigate how to do it - it worth start reading documentation first because no matter which tools you are using in this case.
Below are useful links regarding Visual Studio profiler:
EDIT: Hot Path By VS Profiler:
Upvotes: 1
Reputation: 4565
A simple thing that I like doing first is to use windbg with psscor2. Then i do a !gcroot and/or !GCRef. This sometimes gives insight into the base references that keep the objects alive.
Sorry for that rushed answer, check out for example this blog for some more references if you don't know about psscor2
Upvotes: 0