If you look at the specs of any given generation of iPhone and compare it to the specs of a flagship Android phone from the same year, then you will notice that the iPhone tends to have less RAM. As a result some people have concluded that iOS apps need less memory than Android apps and that the only reason that Android devices have more memory is because Android apps are memory hogs. So the question is this: Does Android use more memory than iOS?
The first thing to establish here is that we are talking about Random Access Memory (RAM), the memory used by the CPU to hold and execute apps. We are not talking about internal storage, which is sometimes called “memory” as it uses “flash memory.”
Here is a look at the amount of RAM in different Apple, Samsung, LG and Nexus devices:
|2016||iPhone 7: 2GB|
iPhone 7 Plus: 3GB
|S7 & S7 Edge: 4GB||G5: 4GB|
|Pixel & Pixel XL: 4GB|
|2015||iPhone 6S: 2GB|
iPhone 6S Plus: 2GB
|S6 & S6 Edge: 3GB|
S6 Edge+: 4GB
|Nexus 5X: 2GB|
Nexus 6P: 3GB
|2014||iPhone 6: 1GB|
iPhone 6 Plus: 1GB
|S5: 2GB||G3: 2GB (16 GB model)|
G3: 3GB (32 GB model)
|Nexus 6: 3GB|
|2013||iPhone 5S: 1GB||S4: 2GB||G2: 2GB||Nexus 5: 2GB|
As you can see the iPhone consistently has less RAM than the equivalent Android devices. The only exception seems to be the Nexus 5X which shipped with 2GB of RAM at a time when the iPhone 6S also had 2GB of RAM. In fact for my testing I used a Nexus 5X (with 2GB) and an iPhone 7 (with 2GB).
The popular claim is that the iPhone gives the same or an even better user experience while using less RAM. When you search on the web for a reason behind this claim the majority of explanations will tell you that Java is the problem and that Android needs more RAM because of Java’s overheads as well as because of Java’s garbage collection. Just let me debunk that myth right now, Java has very little to do with it.
What is free RAM?
Memory management on a modern computing device (PC, laptop, tablet or smartphone) is a complex business. In the good old days a computer had a chunk of RAM with one section for the operating system and then another section for the currently executing program and its data. However that all changed with preemptive multitasking and the advent of virtual memory (VM). I don’t want to go too much into the details of VM now, but basically it allows each program (app) to run in its own virtual address space.
This means on Android and iOS there is RAM given to the OS and then there are sections of RAM (let’s call them pages) given to each app. Any RAM that remains unoccupied is free. But here is the thing, having unoccupied RAM is very inefficient. For example, all input and output (I/O) can be improved by using caching. While caching is important it isn’t as important as running apps. So the OS can give over a portion of the free RAM for caching. Then if more RAM is needed by an app then the caching effort can be abandoned and the memory given to the app. The OS handles all this. What this means is that on a good OS there is hardly any free RAM, but there is “available RAM”, that is RAM that is being used but can be re-purposed immediately.
Once you start down this rabbit hole and use free RAM for other things besides running apps then you soon discover that the rabbit hole is very deep indeed. Modern operating systems like Android and iOS have all kinds of system to re-use unoccupied RAM. The result is a whole vocabulary of terms around memory management including active, inactive, dirty, free, buffered, cached and so on.
The bottom line is this: the amount of free RAM isn’t a useful measure, more useful is the amount of available RAM, RAM that can be given to an app by reassigning it from a less important purpose like caching.
Does Android use more memory than iOS? After a fresh reboot of both the iPhone 7 and the Nexus 5X, the iOS device had 730MB of available memory, while the Android device had 840MB of available memory. That means that Android uses around 100MB less memory than iOS!
Resident Set Size
Just like free RAM isn’t’ the same as available RAM, there is a difference between a program’s virtual size and its real size. Suppose an app asks for one megabyte of memory so that it can load an image from the disk. At the moment the app asks for the memory the apps virtual size will increase, however the OS won’t actually give the app any physical RAM, not yet. So the actual physical amount of RAM used by the app doesn’t increase. Then when the app actually reads the file and starts writing to the memory then the OS will give it some physical memory. If only half of the requested memory is used then the OS might not give it the full one megabyte of physical RAM, it might give it less.
The physical RAM that is actually occupied by an app is known as the Resident Set Size (RSS) and it is a good measure of how much RAM any particular app needs to run. Using the various development tools on Android and iOS it is possible to get a list of the running apps along with the resident sizes.
To test the theory that Android apps use more memory than iOS apps I installed a selection of games and productivity apps and determined their RSS while running. In each case I made sure the app was actually running and doing something useful. For example, with Crossy Road I actually did a few taps and got the chicken across the first road, for the Microsoft Word app I loaded a document and edited a few words. etc.
Here are the results:
As you can see, it is a bit of a mixed bag. The Crossy Road app on Android uses 383MB of memory, while on iOS it uses 308MB. But conversely Temple Run 2 uses 211MB on Android and 364MB on iOS. Overall the trend is that Android apps use slightly more memory, around 6% more than iOS apps. However iOS apps aren’t half the size of Android apps.
It is also important to note that on Android and iOS none of the apps tested used more than 400MB. Now I am sure that there are bigger apps and bigger games out there, but the point I want to make is that for actually running an app you don’t need 4GB on Android or on iOS. Both devices boot with over 700MB of available RAM, so games like Crossy Road and Temple Run can execute without any problems.
Background not foreground
The RSS measurements above are for foreground apps, i.e. apps that are actually running and interacting with the user. But on both iOS and Android it is possible to move away from the current app to do something else and then return to the app later. When you move away from the current app it changes from being a foreground app and becomes a background app. These background apps are treated differently than foreground apps.
The key here is user experience. If I am using Gmail and then I start a solitaire app and play for a little while. After a short time I will likely return to Gmail. My expectation is that Gmail will be running just as I left it. However the next time I take a break I might start Crossy Road. In fact, I might not return to solitaire for several days. The question is what state do I expect to find solitaire after a week of not playing it? Still the same? Closed?
According to the RSS numbers above, if I am using the Microsoft Word app and then I start Crossy Road and then I go back to Word and then I start Temple Run 2, my device will need around 750MB of available RAM. This is on the limit of the available RAM. The story is the same for the iPhone 7 and the Nexus 5X. If I then jumped into another app then the memory needed to keep all these apps in the background, plus start the new app, is more than the available RAM. So what happens now?
The priority for the OS is to get the new app loaded and running, but there isn’t enough available memory, so something needs to happen. On a desktop or server what would traditionally happen is the OS would start to use the hard disk as a temporary store for the pages of memory occupied by background apps. Known as swapping, it is slow, however it does means that older, background programs can be removed from main memory and the memory stored on the disk. If the background program is needed again it can be “swapped in.”
Android doesn’t use storage backed swapping because the write speeds of flash memory are quite slow, plus there is the danger of wearing out the flash. So instead Android and iOS need to do something else. One approach used by Android is to use compressed swapping. The OS will look at the pages that would have traditionally been moved to the hard disk and instead of writing them to a disk they are compressed and stored in RAM. The space saved by compressing the data becomes available RAM. A similar technique is used by macOS since OS X 10.9 Mavericks.
The problem with compression is that it isn’t a fixed ratio. If the memory page stores text or some kind of simple data then the compression ratio will be high and the amount of new available RAM will be high. However if the data is already compressed, like a JPEG image being stored in memory, then the compression will be low. Also compression takes CPU cycles.
However the extra CPU load and the unknown compression ratios are worth it because the alternative is more drastic. If the OS can’t free up enough memory then it has no choice but to kill off another app. Using some clever algorithms the OS identifies which background app needs to be culled and informs the app that it is about to get the chop! The app then needs to save its state (so it can restart in the same place later) and prepare itself for termination.
When a terminated app restarts it will look at its state information and then reload various bits of data and set everything up as it was before, however this takes time and isn’t as seamless as just switching to an app that is already in memory. The classic case is a web page. If the browser gets killed off then when it is restarted it will reload the page you were looking at (as it had saved the URL) but it won’t have an actual copy of the page saved.
On the Nexus 5X I found that I could keep two games (say Crossy Road and Subway Sufers) in memory and switch between them without any problems. However once I started a third game, say Temple Run 2, then one of the other games would be terminated by the low memory killer.
iOS uses the same app assassination technique as Android, however my observations are that iOS seems to have another trick up its sleeves. iOS certainly kills off apps to free up RAM, I have seen it many times during my testing, however this ruthless streak is seen less often than in Android. Instead iOS has a way to reducing the resident set size of an app without actually killing off the app. For example, from earlier we know that Crossy Road takes up around 308MB when it is first loaded. However once Crossy Road is moved into the background I have seen iOS whittle away at its RSS until it was less than 10MB! However the app wasn’t killed off and when I switched to the game was instantly there, without it having to reload. Once in the foreground its RSS climbed rapidly to over 100MB, even to 200MB, but interestingly it never went back to the 308MB limit of the initial load.
As a result when I try the same multiple game test on the 2GB iPhone 7 then I am able to run the first two games, just like Android, but I am also able to run the third game without one of the other two getting killed off.
How iOS is doing this I just don’t know, Apple doesn’t release much information about the internal workings of iOS. Is it using compression like macOS? Is it using a very efficient use of paging, where read-only data that is already on the disk (such as app code) is deleted from memory and then reloaded from disk when needed? I am no Apple fanboy, but I must say I am impressed by how iOS is handling these low memory situations.
Wrap-upWhat this means practically is that iOS doesn’t use less memory than Android or that Android uses more memory that iOS, it means that iOS has a better scheme for dealing with background apps and for re-purposing memory. In general it seems that Android apps which have been moved into the background just sit there in their entirety using up the same amount of RAM they did when in the foreground. On iOS the opposite is true, background apps occupy less memory but the OS keeps just enough so that when the app is switched into the foreground again it is instantly available.
Where Apple’s scheme falls apart is with its split view multitasking support. When running two apps side by side then neither app can reduce its resident set size. Since Android apps and iOS use roughly the same amount of memory then the 2GB on the iPad Air 2 or the iPad mini 4 (both of which support split view multitasking) is really not enough.
It seems that in response to the way Android handles background apps that OEMs have just added an extra 1 or 2GB of memory. That is a perfectly valid solution, however I for one would like to see Android (i.e. Linux) handle background apps differently than it does today.
What are your thoughts? Since RAM is cheap does any of this matter any more? Please let me know in the comments below.