A brief overview of memory in the mobile world

04/04/2014

iOS 7 is the most common operating system used on Apple mobile devices.  It's oldest supported iPhone is the 4 and it's oldest supported iPad is the 2.  So if you are developing an application on iOS 7, your app must be able to operate in a stable manner and perform decently with a measly 512MB of ram on the device.  Then you have to consider the fact that the device's operating system and running processes need a stable of that memory for their running processes and services.  Off goes about 150MBish. The remaining 362MB is not all for you either, thats spread out among the rest of the currently running services and applications.  All in all consider yourself lucky if you end up with 150-200MB of actual usable memory for your application.

So, as you can probably imagine, memory is a very important aspect of mobile development - at least in the objective-c world.  So understanding memory, how to allocate is, reuse, and deallocate it, is a neccessity when developing apps for these platforms.

Memory management has come a long ways since the early days of ios, but a lot of the fundamentals have remained the same. For example, early iOS used to use a management system called reference counting. That is to say that whenever you allocated a space in memory, it had an integer attached to the object called a "retain count". As more things referenced that memory space the retain count would increase. When you no longer needed that pointer, you would release instead of retain.  and if the retain count reached zero, the memory would be deallocated by the OS.

Nowdays we use what is called automatic reference counting, or "ARC". The most important difference in ARC is that the reference counting is handled for you. Basically we do not issue "retain" or "release" counting, but instead reference the memory space in several different ways.  Those references are reffered to as Copy, Strong, and Weak.  If an allocated memory space has no strong pointers, then it is no longer considered neccessary and is deallocated automatically by the operating system.

So why is this important to know?  Why not just use strong references everywhere and not worry about the used memory?  Simply put, if you are building a fairly advanced application with many levels and are not freeing up memory, your app will simply run out of it, and crash.

Lets take an example, so I have a basic app with a homescreen and a button on it, that button has a strong reference to the to viewcontroller holding it (lets say I want the button to get some data from its parent view controller).  When I press the button, it pushes a new homescreen ontop of the stack.  And that has a back button to get rid of the pushed homescreen.  With this setup as I push the button and hit back, I am simply adding more and more homescreens in memory, and that memory, although no longer accessible in the UI.  Will exist forever or until the app closes.

In the iOS world we call these "zombies" because they are no longer accessible to deallocate.  If I change the reference to my viewcontroller into a weak reference, then the deallocation will work fine because the button is not attempting to own the view it is contained in, it is instead just accessing it if it is available, and since the button is removed with the viewcontroller, there are no zombies left at the end.

You can probably see how when you are dealing with a complex app with many components how this can start to become an issue, so it's always a good idea when you are adding a reference to really think about what it is being used for, and how you plan to get that memory back (whether you plan on nulling it out yourself or letting the OS recover it for you.)  The other thing to do is to check that your memory is being deallocated during, and especially near the end, of development.

As a side note, It is interesting to look at how memory is used in collections.  Collections by default, always hold strong references, even when they are mutable.  However in iOS 6 they added a collection defined as a "NSMapTable".  The interesting thing about this collection type is that you can define how it holds on to references.  IE strongly hold weak references, or weakly hold weak references, etc...  This is especially useful if you need a collection of weak references that you dont need to own, that way when ARC trys to deallocate the memory (lets say something UI based) it gets removed from the collection automatically.  Certain situations make this a very useful tool during development.

Comments (0)

The comments to this entry are closed.