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?
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.
heres a method i use:
http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx
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.
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.
Code project currently has a link to an app specifically for finding undisposed objects.
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.