Understanding Instruments in Xcode 3
Instruments is a framework for software-monitoring tools called... instruments. (Capital I Instruments is the application, small i instruments are components of the Instruments application.) The analogy (borrowed from Apple's Garage Band audio editor) is to a multitrack tape deck. Instruments records activity on one or more tracks (one per instrument), building the data on a timeline like audio on a tape.
We've seen Instruments before, in Chapter 19, "Finishing Touches," where it helped us track down a memory leak in Linear. It deserves a chapter all its own.
What Instruments Is
The focus on a timeline makes Instruments unique. We saw how MallocDebug collects allocation and deallocation events, and gathers them into statistical measures, organizing all the stack traces it found at those events into an aggregate call tree, from which you can learn how memory is used. It presents data as an end-of-run accumulation.
Shark, too, works by statistical aggregates. You run your application, Shark samples it, and in the end it presents you with profiling information that is a summary (although very detailed) of all the samples of the whole run. You can filter the samples and manipulate the call trees Shark reports, but the product is still a compilation over a period of time. There is a chart view, but it is still an aggregate, showing the shape of the call stack over time. You can examine stack traces to see what the processor was doing at the time (it can be tricky to select exactly the right one), but there is no way to relate the traces to what the application was doing.
Further, tools such as MallocDebug and Shark do one thing at a time. MallocDebug does heap memory. Shark does profiling (or malloc tracing, or processor events). If you want a different measure, run the application again under the supervision of a different tool. They allow no way to see what one measure means in relation to another.
Instruments is different. It is comprehensive. There are instruments for most ways you'd want to analyze your code, and Instruments runs them all at the same time. The results are laid out by time, in parallel. Did clicking the Compute button result in Core Data fetches? Or had the fetches already been done earlier? Did other disk activity eat up bandwidth? In the application? Elsewhere in the system? Is the application consuming too many file descriptors, and if so, when, and in response to what? You're handing data off to another process (think Linrg, from the first iteration of Linear); how does the tool's memory usage change in response to the handoff, and how does it relate to the use of file descriptors in both the tool and the master application?
Instruments can answer these questions. You can relate file descriptors to disk activity, and disk activity to Core Data events, with stack traces for every single one of these, because Instruments captures the data on a timeline, all in parallel, event by event. And, you can target different instruments on different applications (or even the system as a whole) at the same time.