views:

602

answers:

7

My app was using 150mb of memory not to long ago, now it is at 286mb. It slowly rises so i must be forgetting to dispose something. This isnt much of a problem for me since i have 4gb but i want to send this to others who have only 1gb of ram. other then going through the code line by line how can i find objects that need to be disposed of or just generally large objects?

+2  A: 

Check out the .NET Memory Profiler. There is a 15-day trial and it's well worth the license fee.

Easily identify memory leaks by collecting and comparing snapshots of .NET memory Snapshots include data about the .NET instance allocations and live instances at the time the snapshot was collected. They provide a lot of useful information and make it easy to identify potential memory leaks, especially when two snapshots are compared.

JP Alioto
+1  A: 

heres a method i use:

http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx

willz
+1  A: 

You can also use WinDbg and SOS. These have the advantage of being free and very, very thorough, if a bit tricky to get used to.

Here's a blog post describing the process.

Reed Copsey
windbg and SOS are my fav too. There is a much older blog post from Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx
Remus Rusanu
That was the post that got me hooked on SOS originally... But the one I posted I think is a bit easier to follow.
Reed Copsey
+3  A: 

Extending both JP and Reed's answers.

I wanted to clear up a bit of confusion. If you are seeing significant increases in memory the issue is unlikely to be a problem with calling Dispose. Dispose is typically used to free up unmanaged resources like handles. These don't take up much memory but instead are more precious as resources.

Increases in memory are generally associated with large objects or collections being accessible from a managed object being rooted directly or indirectly via a stack object or a strong GC handle. This is the area you will likely want to focus your investigation on.

JaredPar
Yes, this is a great point. I use the memory profiler to realize things like "oh, that collection should not get bigger and bigger forever!" :)
JP Alioto
Also, take a good look at any events you subscribe to. The event holds a reference to the subscriber, and if you never unsubscribe, that reference is never removed.
JulianR
A: 

Code project currently has a link to an app specifically for finding undisposed objects.

http://www.codeproject.com/KB/dotnet/undisposed.aspx

Khadaji
A: 

Check out this link

Stephen Toub goes into great length to explain various techniques for doing this, Following are some brief highlights from his article

  • By adding a finalizer for debugging purposes, you can introduce a way to find out when a class was not properly disposed,if the finalizer is never invoked, you know that disposed wasn't called

  • To get additional information about the instance, threadIds etc to aid in narrowing down which instance didn't have it's disposed invoked, he creates a FinalizationDebgger class which your disposable class would hold onto which wouldin turn call the Dispose of the FinalizationDebugger class instance when it itself is disposed. If Dispose isn't called on your class instance then when the Finalizer runs it will invoke the finalizer for FinalizationDebgger instance where in you could assert or throw an exception to help debug the problem,

  • Move all the tracking related code into a base class which your disposable class would then inherit from, which makes the code much cleaner. This approach may or may not work since your burn a base class and if you are inheriting from another base already.

  • In the last option everything is factored out into a static class that your instances call into. The FinalizationDebugger becomes a static class that exposes three static methods: Constructor, Dispose, and Finalizer. The idea is that you call these methods from the appropriate place in your class(dispose/finalize/constructor).This is minimally invasive into your code, as it typically involves adding only three lines of code. All of these methods are marked with a ConditionalAttribute such that they'll only be called by your class when you compile your class in DEBUG mode.

Stephen also explains the pros and cons of each of his approaches. The solutions presents various options and you would need to evaluate each to figure out which one works best for your situation. A MUST read IMHO

Hope this helps.

Abhijeet Patel
Need to fill out the answer better to get up votes. Just pointing to a link isn't good enough cause if the link goes don this is no longer a helpful answer.
spoon16
Fair enough, editing the answer to include a brief summary of what is covered in the MSDN article
Abhijeet Patel
A: 
Jon Galloway