This is obviously a loaded question. The memory consumption might not only be caused by memory leaks! Every app is different, and there is no silver bullet, so here some ideas that may help.
get the ANTS profiler, it has 2 weeks trial period + great tutorials. It'll point you to lots of things, like zomby objects, etc.
WPF is a hog, so the more tabs you open (controls that don't go away) the more memory it will take. Look through your XAML, can you trim it down. For example, use TextBlock instead of labels. Remove extra nested controls, like StackPanel within a StackPanel, or Grid within a Grid, within a stackpanel - put all those in one grid, and make use of row/columns.. If you have an item template where each item does something that makes it complex, try to change that. For example, if on focus it draws a border around the item and does something fancy, ask a question, can I remove that from each item, and create one control that calculates its location and places itself aproprietly.
Do you have the Views (usercontrols, or controls) per tab that are the same type, just a different instance? If so can you recycle them? I was on a project a year+ ago where we had some menu creating a tab for some criteria, and then another, and another. Criteria was different, but the view type was the same. It was just being injected with different info - Prism was creating a new View control for each one of these tabs, which is obviously expensive. What we ended up doing is creating different ViewModels, but keeping the same instance (recycling by removing/adding back when needed to the region) of that expensive view.
To do so each ViewModel would on navigation (sample)
//detaching from Prism region allows for recycling
public override void OnNavigatedFrom (NavigationContext navigationContext)
var view = _container.Resolve (typeof (Object), "NameOfTheView");
if (view != null)
//similarly you can readd it where your think it is nedded..
public override void OnNavigatedTo (NavigationContext navigationContext)
this link can be useful:
Note on Garbage Collection:
The whole purpose of the .NET garbage collector is to manage memory on our behalf.
However, in some very rare circumstances, it may be beneficial to programmatically force a garbage collection using GC.Collect().
a.When your application is about to enter into a block of code that you don't want interrupted by a possible garbage collection.
b.When your application has just finished allocating an extremely large number of objects and you wish to remove as much of the acquired memory as soon as possible. (this was the case in my project)
c. also: http://blogs.msdn.com/b/ricom/archive/2004/11/29/271829.aspx
I would definitely implement Dispose methods on every ViewModel, where I would set everything big to null, don't forget to unsubscribe from events, and things like timers. You could call GC.Collect (); but read the note above on that.. Don't forget to clean up complex object, don't just set them to null. For example, in my Dispose we had something like:
which in turn was doing this:
private void ClearDisplayGrid ()
foreach (var r in DisplayGrid.MyItems.SelectMany (it => it.SubItems))
r.IsSelectedChanged -= ReadingIsSelectedChanged;
r.InEditChanged -= ReadingInEditChanged;
r.PropertyChanged -= ReadingPropertyChanged;