Memory management is something really critical, because it can reduce the application stability. A very important topic in software development is the quality control (QA). It is the moment in which the developer should check how the application behaves in term of resource and processor usage.
You already know that when you allocate an object with the sequence alloc-init, you need to release the object, otherwise the object keeps part of the memory for ever. If this happens very often in your code, the result can be a disaster: the application crashes or starts to become very slow and then, crashes. The Garbage Collector is a possible solution to this problem, but you cannot always use it (Cocoa Touch does not have a Garbage Collector).
Apple provides us with a large set of tools, which can help us to dynamically analyze our application. Instruments offers you this tools. Even if Apple suggests to use always Instruments, I have to say that the available documentation is quite poor in term of operations. This quite forces many developers to skip this very important phase of the development. You can see this in the poor quality of many applications sold in the AppStore. If one of your iPhone app crashes, it is quite probable that the developer did not use Instruments.
In this post, I will show you how to use Instruments to solve memory leaks. In future post, we will see how to use other analysis tools.
You can launch Instruments in different ways. For sure, the most convenient way is to use the Xcode menu while you are working on your project. After building the project, choose Start with Performance Tool -> Leaks from the menu Run.
Instruments launches. Immediately after, your application is executed and Instruments starts to record data.
If you launch Instruments double-clicking its icon, then you need to add the app you want to analyze (Default Target) and press the Start button.
While Instruments is recording the data, use your application. When you feel you have enough information, stop the recording. If you notice well, Instruments loaded two tools: Leaks and ObjectAlloc. ObjectAlloc is useful to track each object during its life from its creation until its destruction. On the other hand side, Leaks is useful to find leaking objects.
In the upper part of the window (see next picture), there is a small triangular cursor that moves during the recording session. Using the Inspector Range, you can filter our the results of your analysis in a defined time interval. This can help you to localize easily what happens in a specific period of time in your application.
Now, select View->Detail. You get a new view with the information about each object category created during the recording session. The table view shows the object type (Category), the number of objects assigned to the memory and still alive (# Net), the overall number of objects (#Overall), the quantity of used memory in both cases (Net Bytes and Overall Bytes) and finally a proportion between the number of object still in memory and the total number of assigned object (#Allocations (Net/Overall)).
If you select any of this objects, you see a small arrow on the right side of the object category.
Click on this arrow. Instruments show you every object of this category created during the recording session.
If you click on any of them, you get the details related to that particular object.
The Event Type columns shows a list of Malloc, Free, CFRelease, CFRetain, etc. and the method that generated that event (Responsible Caller). If you select one of the events and open the Extended Detail from the View menu, Instruments provides you with more information about the selected object. The Extended Detail view is very important, because it contains direct links to the chuck of code generating the memory leak. To make it more useful, click and hold on the small gear icon and choose all the detail as shown here.
The ObjectAlloc tool is very useful to improve how your application responds to your touches. Indeed, it is very common to create objects o load data into the memory when we do not need them. If this happens with a very large number of objects or a considerably large data set at the same time, your app starts to slow down and does not respond quickly to the user interactions as it should do. Using ObjectAlloc you can find where this problem occurs and improve your code.
Let’s look at the Memory Leak detail. The Leaks tool shows the leaking objects. If you get a pulse similar to what is shown in Figure 2, then, you have a memory leak and you need to solve it.
Click on the Leaks tool. In this way, in the lower view you get the list of the leaking objects (Leaked Blocks). Now, your analysis begins.
Carefully, you need to analyze each object of the list, one by one. Don’t be scared. Even if your list is very large, most of the time it is sufficient to solve only few of the leaks in the list, due to the object dependency. The column Self% can be useful. Start always your analysis with the object showing a big Self%.
Once you select an object, Instruments shows you the life of that object (a sequence of events showing the object creation, the retain and release sequence, and so on). If your object is leaking, the reason is that a retain or a release is missed in the chain. Look at the column and find where this happens. Then, open the Extended Detail view (View -> Extended Detail). Its General section shows the Retain Count of the analyzed object.
The Stack Trace of the Detailed View is similar to what is shown here.
In this example, you can see that a vector (CFArray) has been created (Malloc) and its Retain Count is 1. This events has been generated by the viewDidLoad method. If you double click on this (the line #2 of the Stack Trace), Instruments calls Xcode at the code line generating this problem. Next picture shows this code. As you can see, the array anArray has been created with alloc-init, but never released. This generates the Leak. To fix it, it is enough to release this object before the end of the external for-loop.