Run perfmon -- there are many new counters added for the .NET FCL that will help. Specifically, I'd pay attention to the .NET CLR Memory Gen0 Heap Size and Large Object Heap size.
Recall that the garbage collector categorizes allocated memory into Gen0, Gen1, Gen2, and LargeObject areas. Gen0 objects are your typical local variables, etc. If they meet certain criteria (mainly how long they've existed) they get promoted to Gen1, and then to Gen2.
When a GC cycle runs, Gen0 objects are checked for reachability, and those that are no longer reachable by your code are freed. The memory is then compacted. If there isn't enough memory available, the Gen1 objects are freed/compacted, and if there still isn't enough memory the Gen2 objects are freed/compacted.
The LargeObject area is for variables larger than about 85,000 bytes (may change in future releases). These objects are never compacted because moving them around would take too many CPU cycles. As a result, if you have a large number of weighty objects you can get memory fragmentation.
Chip H.