I have a large website that seems to be sucking up all the memory that is being allocated. There is nothing else on the server beside this site. Within a week it eats away the 2 gigs and requires a restart. Currently this is server 2008 32 bit using IIS 7. We are reinstalling to use 64bit and add more memory. It would be nice to be able to track down where the leaks are occurring.
So what is the best practice to tracking memory leaks?
Check out the Memory and Memory Leak labs on this blog post:
.NET Debugging Demos
They may be of some help. Basically, you can use WinDBG to analyze a memory dump and help determine what is eating up all of your memory.
We used a similar approach to determine that Regex was chewing up all of our memory, but only when the product was run on 64-bit machines. The learning curve is kind of steep, but WinDBG is a very powerful tool.
In performance monitor, add counters for Process/Private Bytes and .NET CLR Memory/# Bytes in All Heaps. Private bytes is all memory and CLR memory is just managed. So if the CLR memory remains fairly even but the private bytes continues to grow over time, this means that the leak is in unmanaged resource. That usually means that you are not disposing of native resources properly. A good thing to look at is stuff like COM or IO (streams and files). Make sure all of that stuff gets disposed when you are done with it.
Look at this article on detecting .NET application memory leaks and related articles mentioned at the bottom of the page and hopefully you will find a solution or at least an idea to resolve it.
Thanks
Do you have lots of dynamic pages on your site?
You can also try IBM's Purify
I suggest you try with a small set of dynamic pages disabling all others for the meantime. I hate to say this but it's very much possible that IIS 7 may also have leaks.
Memory leaks in .NET are not that common, but when they happen it is most commonly due to unattached event handlers. Make sure you detach handlers, before the listeners go out of scope.
Another option is if you forget to call
Dispose()
onIDisposable
resources. This may prevent cleanup of unmanaged resources (which are not handled by GC).And yet another possible reason is a deadlocked finalizer. That will prevent all remaining objects in the finalizer queue from being collected.
I use WinDbg + Sos to track down leaks. The steps are as follows
!gcroot
to find out what is keeping the suspects aliveBe aware that large memory usage may also be due to heap fragmentation. The regular heaps are compacted, but pinned objects can cause fragmentation. Also, the LOH is not compacted so fragmentation is not uncommon for LOH.
Excellent tutorials on WinDbg + sos here: http://blogs.msdn.com/tess/
This new article of mine maybe useful: How to detect and avoid memory and resources leaks in .NET applications