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 */ serviceIntent.putExtra(Intent.EXTRA_EMAIL, replyMessenger); context.startService(serviceIntent); } private Handler mAckHandler = new Handler() { @Override 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) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); } } @Override public int onStartCommand(Intent intent, int flags, int startId) { //If intent has a message, queue it up Message msg = mServiceHandler.obtainMessage(); msg.obj = intent; mServiceHandler.sendMessage(msg); return START_STICKY; } private void onHandleIntent(Intent intent) { Messenger replyTarget = intent.getParcelableExtra(Intent.EXTRA_EMAIL); /* Do some work */ Message delivery = Message.obtain(...); replyTarget.send(delivery); } } 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. [image: 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 android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en