I have been trying to fix memory leaks in my application for quite a while. Few months back, I noticed that in my application, more than 95% of the objects get promoted to Gen2; and I have some very basic questions which I have not been able to find in books. I hope you guys can help me:
Thank you in advance.
Does having so many Gen2 objects a bad news?
This is not the bad news. It could mean that GC.Collect has just run, or it is run pretty often, and you have plenty of free memory - therefore objects in Gen2 are not collected. Here is some good explanation from another StackOverflow question, Garbage Collection not happening even when needed:
When starting a garbage collection, the GC determines what generations need to be collected (0, 0+1, or all). Each generation has a size determined by the GC (it can change as the application runs). If only generation 0 will exceed its budget, that is the only generation whose garbage will be collected. If the objects that survive generation 0 will cause generation 1 to go over its budget, then generation 1 will also be collected and its surviving objects will be promoted to generation 2 (which is the highest generation in Microsoft's implementation). If the budget for generation 2 is exceeded as well, garbage will be collected, but objects can't be promoted to a higher generation, as one doesn't exist.
So, here lies the important information, in the most common way the GC is started, Generation 2 will only be collected if generation 0 and generation 1 are both full. Also, you need to know that objects over 85,000 bytes are not stored in the normal GC heap with generation 0, 1, and 2. It's actually stored in what is called the Large Object Heap (LOH). The memory in the LOH is only freed during a FULL collection (that is, when generation 2 is collected); never when only generations 0 or 1 are being collected.
To your second question:
How can I find out the reason so many objects are getting promoted? Is there a good tool? I have been using WinDbg/SOS mostly and I haven't had much luck
Windbg and SOS is good :) In this situation I would suggest to add psscor2 (or psscor4, if .NET 4.0 is used) You need to use psscor to dump object of specific generation easily.
Here are official links to download psscor2 and psscor4 dlls. Put appropriate versions of them to the folder where Windbg is installed. x86 versions of dlls to x86 folder (C:\Program Files (x86)\Debugging Tools for Windows), x64 versions of dlls to x64 folder (C:\Program Files\Debugging Tools for Windows (x64)).
Then you will be able to run next command:
!dumpheap -gen 2
SOS doesn't have easy command to dump objects only of specific generation, when psscor does.
Using this command, you may create constructions like
.foreach (obj { !dumpheap -gen 2 -short }) { !do ${obj} }
or
.foreach (obj { !dumpheap -gen 2 -type ExactTypeName -short }) { !gcroot ${obj} }
to find out main types of the objects in gen 2, and which methods reference them.
As you said, that your main idea is to find memory leaks, you should use more general approach, and analyze not only generation. Here are my posts on analyzing high-memory-usage issues:
managed memory:
http://kate-butenko.blogspot.com/2012/06/investigating-memory-issues-high-memory.html
unmanaged memory:
http://kate-butenko.blogspot.com/2012/07/investigating-issues-with-unmanaged.html
http://www.codeproject.com/Articles/31382/Memory-Leak-Detection-Using-Windbg
Please leave your questions if you are still stuck on some step.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With