Plugging Native Memory Leaks on Android

You may have noticed that mobile applications do not have a “Quit” button. They essentially run forever, until either the user or the operating system kills the application. This means that if your application has a memory leak, even a small one, the memory usage of the application can grow very large over time.

I had to track down a memory leak in our native code just this week, and it was a bit of a pain so I thought I would share my findings. I am using OSX for development, so if you are on Windows you can figure out the corresponding location of the various files.

First you will need to configure the Android utility ddms (Dalvik Debug Monitor) to display the native heap. You do this by editing the ddms.cfg in the directory “.android” in your home directory. Add the line “native=true”. Now when you launch ddms, you will see a new tab for the native heap:

Now you launch your application on your phone while it is plugged into the USB port. You click the “snapshot current native heap usage” button and … nothing happens.

It turns out that native allocations are not tracked by Android unless you are using the debug malloc library. You can enable this by running the following commands:

adb shell setprop libc.debug.malloc 1
adb shell stop
adb shell start

Now you click the snapshot button and … still nothing happens.

Guess what – unless your phone is rooted, you won’t be able to set this property and get the native heap allocation information out.

So now what? You have two options. Root your phone, or use the emulator. The Android emulator is extremely slow, but in this case, I was able to use it to reproduce the problem that caused the leak. I created a virtual Android device for 4.0 and launched the emulator. After running the commands to enable debug mallocs, the native snapshot finally returned allocation data.

As I searched the web to find this information, I saw several questions asking how you would use this heap snapshot tool to find a leak. It is really straightforward. Just take a snapshot at a point before the leak, take another snapshot after the leak, and then diff the two snapshots with your favorite diff tool to see what allocations are still hanging around after the leak.

So what was the particular leak I found? It turned out to be a texture for a 3D model. The texture was about a meg in size, which corresponded to the 1meg leak I was seeing each time a model was loaded and unloaded.

This entry was posted in Uncategorized and tagged . Bookmark the permalink.

2 Responses to Plugging Native Memory Leaks on Android

  1. Jeff Tunnell says:

    Just testing. I’ll tweet this and see if it gets any traction.

  2. Roger Huang says:

    Thanks, this is really useful. But have you tried native heap debugging in newer versions of Android? I’m wondering if Android stop supporting this feature since API 19.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s