In the first two parts of this series (part 1 and part 2) I described how to get started using the CLRProfiler and how to use the histograms and the "Show Who Allocated" view to see what types of objects you're allocating and to determine where in your application the allocations are occurring.
In this post I'll talk about my favorite view: the Timeline view. I like the Timeline view because it lets you look at the contents of the GC heap over time. Using this view you can see not only where in your application you are allocating objects, but when. You can also see which objects are collected each time the GC ran. By including a time dimension, the Timeline view combined with "Show Who Allocated" can give you a complete picture of how the use of managed memory varies as your application runs.
After you've completed profiling, you can launch the Timeline view from the Summary page:
The Timeline View
The Timeline view has two panes. The right hand pane is the legend and the left hand pane is the contents of the heap. As with the histograms we looked at in part 2, the colors in the legend describe the types of objects present in the heap. Free space in the heap is always white:
The horizontal axis in this view represents time. If you look at the axis you can see when each GC occurred as indicated by the vertical blue markers. By correlating each GC with the contents of the heap displayed above you can get a sense for which objects were freed in each collection.
Note: You may notice that each GC is labeled with a generation. The Compact Framework's garbage collector doesn't have the notion of generations so these markers are an artifact of the code we ported from the full .Net Framework. You can ignore them.
The vertical axis in the timeline view shows object addresses in the heap. Given that the segments of the GC heap are not necessary contiguous you may seen gaps in these numbers. If you'd like more information about the Compact Framework GC check out the following posts:
- An Overview of the .Net Compact Framework's Garbage Collector
- GC Heap Management
- Don't Fear the Garbage Collector
Back to the Example
Throughout this series of posts I've been using an example of a game I wrote that paints way too slowly. In part 2 we saw that the vast majority of objects I'm creating are of type Box.Block. Looking that the Timeline view confirms this as can be seen by looking at the legend and all the red in the view of the heap.
The time-based nature of this view allows us to get a few steps deeper into our analysis. First, we can see the points in time at which allocations of our Blocks occurred. In this case, that data isn't very interesting because the view tells me that I was almost continually allocating Blocks.
What's more important in my case is to discover which method in my application was doing the allocations at which point in time. It may be that early on in my application my allocations were coming from MethodA while later on they were coming from MethodB. This time-based analysis can be particularly useful if you'd like to see all that's happening when your application first starts, for example.
To see where your allocations are coming from at a given point in time just select that time in the view. This causes a vertical line to appear at that point in the graph. Then right-click and select "Show Who Allocated" from the context menu:
Doing so brings up the same Allocation Graph we looked at in part 2, except that the graph shows only the allocations done at that particular point in time. In part 2 we saw that my allocations were coming from two methods: InitializeGameBlocks and RotateGameBlocks. By using the timeline view I can see which of those methods was called at which times during my application.
Next time I'll describe the Call Tree view that will show even more detail by highlighting the exact lines within my methods that are causing the spurious allocations to occur.
This posting is provided "AS IS" with no warranties, and confers no rights