Windbg, is there anything it can't do?
CLR Profiler is great for getting an overview of memory allocations and usage for managed applications but it doesn't work for very large applications and can't be attached after the application has been running for a while to determine why after 12 hours memory use spikes. Windbg can be an acceptable alternative when you find yourself looking at an unexpected memory spike and you're curious where all that memory is being allocated.
Start Windbg, attach to the process, and load the sos dll (see previous post).
We start out by getting a summary of our memory allocations with !dumpheap
We've got about 3 megs worth of System.Byte allocated so let's focus in on this to see why these objects exist.
A few small Byte arrays but 3 of them are a meg each so let's find out why the first object is still alive (or if it is alive at all, a GC might not have happened to collect it yet).
The application has a reference to Form1 which has a reference to an ArrayList which has a reference to my Byte array. If a GC were to happen right now this object would be kept alive.
Instead of checking each Byte array by address individually we can use the .foreach token.
By using the /ps parameter to .foreach (see Windbg help file for details) you can run gcroot on every nth item to get a sample of objects.