That moment when one Dalvik alone is no longer enough.

Living with memory constraints

There are many aspects that make Android unique as a mobile OS, but sometimes it can be quite tough to approach, especially from a developer standing point.

Take the memory restrictions, for example. With iOS offering virtually no limit on an app’s memory budget (say, 200 MB is not a big deal), Android has heavy limitations that go from 24/32/48 MB for the most recent devices to a minuscule 16 MB for older devices.

That RAM budget is everything your app has got to work with. Meaning, it must be sufficient for loading classes, threads, services, UI resources AND the content your app wants to display. Imagine a photo browsing app with a grid of awesome pictures, or a music player that needs to play in the background: the horror.

Life’s a bitch, sometimes.

To understand why Android poses these restrictions and what solutions it offers to cope with them, we need a tiny little bit of background about what’s happening under the hood.

Android processes: explained!

You should already know by now that Android is based on Linux. As such, each application runs in its own process (with a unique PID): this allows the app to live in an isolated environment, where it cannot be hindered by other applications/processes. Typically, when you want to start an application, Android creates a process (forking the Zygote), spawns the main thread and starts running the main Activity.

What you probably don’t know is that you can specify some components of your app to run on a different process than the one that was used to start the app. Meet this nice little attribute:

android:process

The process attribute can be applied to activities, services, content providers and broadcast receivers and specifies what process that particular component should be executed in.

In this example, I’m specifying that the MusicService must be executed in a separate “music” process:

<manifest ...>

<application

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/Theme.Main" >



<activity

android:name=".MusicActivity"

/> <service

android:name=".MusicService"

android:process=":music"

/> </application>

</manifest>

What good is it, then?

In the introduction, I mentioned that each Android app has a memory budget for its execution that cannot be exceeded. To be precise, that limit is enforced in a per-process basis. In other words, each process of an application will have have a dedicated memory budget! (not to mention different rules for its termination, which is even more cool)

Let’s see whether this approach is going to be a good thing or a bad thing. [spoiler: it’s going to be both]

What’s cool about having multiple processes

As I just mentioned, a separate process can take advantage of its own RAM budget, allowing the main process to have more space for its resources.

In addition, processes that run different components are treated differently by the OS. This means that, in conditions where the system is running low on available memory, not all of them are to be killed. Consider this: your music player is running in the background and the music is playing; suddenly, the system needs to free some memory (because Facebook, that’s why). Since the service that plays the music runs on another process, it is extremely likely that the OS is going to kill the main process first (the one that runs mainly your app UI), leaving the music playing in the other process.

On a final note, this looks good for the end user as well! Because each of your app’s processes will have its own entry in the RAM usage screen of the Application Manager, and chances are that one or more of them are going to appear in the “Cached” section (which means they are inactive).