Thursday, August 30, 2012

[android-developers] Messenger from Remote Service Causing Memory Leak

I have an application that communicates with a Service in a remote process using the Messengerinterface. Here is the basic architecture of how things are set up:

  • The application generates several "Operation" objects that require access to the service.
  • Each "Operation" contains a Handler wrapped in a Messenger used as a callback receive the response data back from the Service
  • When the operation executes, it wraps its Messenger into an Intent and calls startService() to pass the message to the remote service
  • The remote service does some work based on the parameters of the Intent and then returns the response by sending a Message to the Messenger for that operation.

Here is the basic code present in the operation:

public class SessionOperation {

/* ... */

public void runOperation() {
Intent serviceIntent = new Intent(SERVICE_ACTION);
/* Add some other extras specific to each operation */
.putExtra(Intent.EXTRA_EMAIL, replyMessenger);


private Handler mAckHandler = new Handler() {
public void handleMessage(Message msg) {
//Process the service's response
protected Messenger replyMessenger = new Messenger(mAckHandler);

And a basic snippet of how the service is structured:

public class WorkService extends Service {
private ServiceHandler mServiceHandler;

private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {

public void handleMessage(Message msg) {

public int onStartCommand(Intent intent, int flags, int startId) {
//If intent has a message, queue it up
Message msg = mServiceHandler.obtainMessage();
.obj = intent;


private void onHandleIntent(Intent intent) {
Messenger replyTarget = intent.getParcelableExtra(Intent.EXTRA_EMAIL);

/* Do some work */

Message delivery = Message.obtain(...);

This all works fantastically well. I can send tons of operations from several different applications to the same service and they all process and send their response to just the right place. However...

I noticed that if the application ran long enough and with enough activity it would crash with anOutOfMemoryError. Upon looking at the HPROF data in MAT, I noticed that all these operations where staying in memory, and they were held hostage from the Garbage Collector because of theMessenger. Apparently, the Messenger instance is creating a long-term native connection to Binder that counts as a GC Root, which is keeping each "Operation" object in memory indefinitely.

MAT Trace Example

Does anyone know if there is a way to clear or disable the Messenger when the "Operation" is over so it doesn't create this memory leak?

Is there perhaps a better way to implement the IPC to the Servicein the same fashion, so that multiple disparate objects can make a request and get a result asynchronously?  I'm not convinced that just switching to using a bound service implementation will solve this issue as I would will need the Messenger to process the callback.

You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to
To unsubscribe from this group, send email to
For more options, visit this group at

No comments:

Post a Comment