.NET Forum / .NET Framework / Performance / July 2005
Performance monitoring indicates that GC is not running?
|
|
Thread rating:  |
Wade - 11 Jul 2005 15:53 GMT Hi all,
Let me first admit that, despite everything I've been reading on GC in .NET, I still don't get it. In fact, what I've learned is probably just enough to help confuse the entire issue for me ...
Nevertheless, I've been monitoring performance on one of our LIVE servers the past couple days, and I don't understand what it is that I am seeing with the .NET CLR Memory counters.
For example, I came in this morning (Monday) at 6:30am and reviewed our LIVE servers. Looking at our IIS logs, it appears that we had no web traffic over the weekend, and there was no one currently using our .NET application. Yet, here's the information I got from the .NET CLR Memory counters:
# Bytes in all Heaps: 57,511,516
Now, perhaps I'm misunderstanding what this is telling me, but this indicates to me that we have all kinds of .NET objects still persistent in memory, and that either 1) GC hasn't been running to clean them up or 2) when GC has run there have still be references to the objects and they haven't been destroyed. Right?
Essentially, I'm simply trying to find a way to monitor what's happening with GC, and then interpret what's been monitored.
If anyone has any thoughts, opinions, suggestions, or explanations, please let me know. Thanks!
Wade
Alvin Bruney [MVP - ASP.NET] - 12 Jul 2005 02:14 GMT it's more likely that the GC has not run. before you jump off the cliff, you should know that this behavior is by design. you typically get a collection when there is memory pressure. it doesn't occur when objects are out of scope or have no live references. it simple means that these objects are eligible for collection. in your case, the great .net runtime has determined that it doesn't need to collect these objects...
 Signature Regards, Alvin Bruney - ASP.NET MVP
[Shameless Author Plug] The Microsoft Office Web Components Black Book with .NET Now available @ www.lulu.com/owc, Amazon.com etc
> Hi all, > [quoted text clipped - 27 lines] > > Wade Wade - 12 Jul 2005 20:02 GMT > before you jump off the cliff Phew! Glad I just read this ... I was heading out the door!
> you should know that this behavior is by design, you typically get a > collection when there is memory pressure. it doesn't occur when objects > are out of scope or have no live references. Okay, then it's confirmed that I really have no idea what's going on.
However, I do have a question -- if I implement the IDisposable interface, overload the Dispose method and explicitly call GC.Collect, shouldn't GC run?
I created a test in which I did this -- I watch as the process ran, and it consumed around 180 MGBytes of RAM, but once it was finished it didn't seem to be released.
Am I still missing the point?
Thanks for the help!
Alvin Bruney [MVP - ASP.NET] - 13 Jul 2005 14:52 GMT No, you probably do have a genuine problem. The memory should have been released with the GC.collect, assuming it ran. Firstly, you should be using a memory profiler instead of windows task manager for an accurate picture. What is the total size memory on your system? Once you have a profiler, you should write a simple routine to allocate memory continually. Monitor it thru the profiler. When memory gets above 60% or so, the collector should run and the memory should fall back down. If you run into an out of memory condition, you may likely have a problem.
 Signature Regards, Alvin Bruney - ASP.NET MVP
[Shameless Author Plug] The Microsoft Office Web Components Black Book with .NET Now available @ www.lulu.com/owc, Amazon.com etc
>> before you jump off the cliff > [quoted text clipped - 17 lines] > > Thanks for the help! Wade - 13 Jul 2005 18:23 GMT The 60% you mention is the value specified in the processModel of the machine.config file, right? If so, then that could very well be the problem -- I'm calling GC.Collect(), but I haven't consumed enough memory to make GC think it needs to release it.
I'll try your suggest and write a "memory hog" routine, and monitor it with the .NET CLR Memory counters (which I was using).
Thanks for the advice!
Wade
> No, you probably do have a genuine problem. The memory should have been > released with the GC.collect, assuming it ran. Firstly, you should be [quoted text clipped - 26 lines] >> >> Thanks for the help! john conwell - 13 Jul 2005 17:39 GMT Hi Wade, there are a few things that could be going on. First and formost, just because you explicitly call GC.Collect does not mean the GC is going listen to you and do a manual collection. If it 'thinks' that it is more efficient to not perform a collection, it wont.
Second, in your IDispose example, were you looking at "bytes in all heaps" or just the memory taken up by your process. Every process has a working set of memory. when the GC does a collection it releases memory back to the processes working set, but the process may or may not release that memory back to the OS. This is because if the CLR later needs to allocate more memory for the GC heaps, it can just pull it from the working set, and not request it from the OS. This makes it more efficient, especially for a web server because there are times when it'll need to allocate a lot of memory to the GC when the load increases.
At the surface, .Net looks like it is a memory hog, but most of the time its just holding onto extra memory in case it needs it. But if system resources start to get slim, it will relenquish its extra memory back to the OS.
A third possibility is that you have a legidimate problem :-)
> > before you jump off the cliff > [quoted text clipped - 17 lines] > > Thanks for the help! Wade - 13 Jul 2005 18:23 GMT Thanks for the tips, John.
I was actualy looking at the asp.net worker process, rather than the "bytes in all heaps" -- I'll try again and take a look.
Thanks,
Wade
> Hi Wade, > there are a few things that could be going on. First and formost, just [quoted text clipped - 49 lines] >> >> Thanks for the help! Phil Wilson - 14 Jul 2005 02:33 GMT You're not running with debug builds of your .NET code are you?
 Signature Phil Wilson [Microsoft MVP-Windows Installer]
> Thanks for the tips, John. > [quoted text clipped - 61 lines] >>> >>> Thanks for the help! Dave Black - 14 Jul 2005 06:16 GMT This may be a dumb question but does it make sense to run a Memory Profiler (such as CLR Profiler, Compuware's DevPartner Profiler, etc.) against Debug or Release builds? I know that each handles memory differently but is there any value in profiling against a Debug build?
TIA
> You're not running with debug builds of your .NET code are you? > > Thanks for the tips, John. [quoted text clipped - 62 lines] > >>> > >>> Thanks for the help! john conwell - 14 Jul 2005 16:48 GMT debug and release builds do handle memory a bit different, but when talking about bytes in all heaps i've found that they are the same. a double is a double is a double no matter how its compiled. A object pointer is the same size, a datarow takes up 40 bytes no matter how its compiled.
Now there is other memory overhead for debug 'stuff' but the size of values in the GC heaps are the same
> You're not running with debug builds of your .NET code are you? > > Thanks for the tips, John. [quoted text clipped - 62 lines] > >>> > >>> Thanks for the help! Dave Black - 15 Jul 2005 05:41 GMT Hi John,
Yes the values are the same but I believe the initialization of the values and the aggressiveness of the GC are different between Bebug and Release builds.
> debug and release builds do handle memory a bit different, but when talking > about bytes in all heaps i've found that they are the same. a double is a [quoted text clipped - 70 lines] > > >>> > > >>> Thanks for the help!
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|