One of the more difficult things about getting started with .NET Debugging is the mental shift that you have to make.
The first problem that I had with .NET was trying to look at everything using dd and just walking through memory. I was very used to reading assembly and walking linked lists in the dump. I used dt a lot to dump out structures and see what the values of things were. I was also accustomed to searching through the NT heaps for data and looking for problems there.
With .NET, none of that is how you do things. You don’t look through memory in the same way and don’t go looking through the heap to find issues. But it actually goes a bit deeper then that as well.
Thinking about a problem completely changed for me. If it was high memory and I determined it was .NET that was using most of the memory, I had to get away from trying to look for the largest allocation or largest group of allocations of the same size. Since .NET handles all allocations, that won’t help you much as you can’t find anything useful there.
Another shift was what would cause problems. In native code, it is rather hard to cause memory problems using strings (for example). But it is very easy with .NET. So the trick was not only changing how you think about getting to the information, but also what that information means. It takes a very good understanding of how .NET functions in order to properly understand what is and what is not a problem. For more proof, compare the debugging sessions that I explain on this blog, High Memory part 5 – Fragmentation, (for example) with one from the NT Debugging folks, like How to track down High CPU in User Mode Applications - A live debug!