我有一个使用Service
接口(interface)在远程过程中与Messenger
通信的应用程序。这是事物设置的基本架构:
Handler
,该Messenger
包装在Service
中,该Messenger
用于接收来自Intent
的响应数据startService()
包装为Intent
,然后调用Message
将消息传递给远程服务Messenger
的参数进行一些工作,然后通过向该操作的IntentService
发送OutOfMemoryError
来返回响应。 这是该操作中存在的基本代码:
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);
}
以及如何构造服务的代码段(基本上是一个
Messenger
,当队列为空时它不会关闭):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);
}
}
所有这些都非常出色。我可以将大量操作从几个不同的应用程序发送到同一服务,它们全部处理并将响应发送到正确的位置。然而...
我注意到,如果应用程序运行了足够长时间且具有足够的 Activity 性,它将因
Messenger
崩溃。在MAT中查看HPROF数据时,我注意到所有这些操作都保留在内存中,由于Messenger
,它们被垃圾收集器作为人质。显然,Service
实例正在创建与Binder的长期本地连接,该连接被视为GC根,从而无限期地将每个“Operation”对象保留在内存中。有谁知道“操作”结束后是否有清除或禁用ojit_code的方法,从而不会造成此内存泄漏?是否可能存在另一种以相同方式将IPC实现到ojit_code的方法,以便多个不同的对象可以发出请求并异步获取结果?
提前致谢!
最佳答案
感谢Android团队的Dianne Hackborn的一些非常有帮助的见解,该问题是因为远程服务进程尚未垃圾收集它的Messenger实例,实际上该实例一直将实例保留在应用程序的进程中。
这是她的回复文本:
更多信息:
https://groups.google.com/d/msg/android-developers/aK2o1W2xrMU/Z0-QujnU3wUJ
关于android - Messenger到远程服务导致内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12204740/