我最近遇到了一个奇怪的内存问题。每次我启动 MyActivity(它启动 MyService)时,我的应用程序的内存使用量都会增加。因此,在启动和完成 MyActivity 几次后,我的应用程序内存不足。在启动和完成 MyActivity 两次后,我进行了堆转储。我发现内存中有 2 个 MyService 实例。在我执行“传入引用”->“gc 根路径”之后,我得到了以下行(在两个实例上):
com .....MyService @ 0x42746880
->this$0 com.....MyService$MyServiceBinder @42746928 本机堆栈
我的代码与此类似:
public class MyService extends Service {
...
public class MyServiceBinder extends Binder{
MyService getService(){
return MyService.this;
}
}
}
public class MyActivity extends Activity{
private MyService service;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
launchService(savedInstanceState==null); //start MyService
}
...
@Override
protected void onStart(){
super.onStart();
if(clientService == null)
getApplicationContext().bindService(new Intent(this, MyService.class), connection, Context.BIND_NOT_FOREGROUND);
}
@Override
protected void onStop(){
super.onStop();
if(clientService != null)
getApplicationContext().unbindService(connection);
}
@Override
protected void onDestroy(){
super.onDestroy();
}
@Override
protected void onBackPressed(){
service.destroyService(); //stops MyService ->calls stopSelf inside MyService
finish();
}
private LocalServiceConnection connection = new LocalServiceConnection(this);
private static class LocalServiceConnection implements ServiceConnection{
private final WeakReference<MyActivity> parent;
private MyActivity activity;
private MyServiceBinder binder;
public LocalServiceConnection(MyActivity parent){
this.parent = new WeakReference<MyActivity>(parent);
}
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
activity = parent.get();
if(activity==null)
return;
binder = (MyServiceBinder) arg1;
activity.service = binder.getService();
...
activity = null;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
activity = parent.get();
binder = null;
if(activity==null)
return;
activity.service = null;
activity = null;
}
}
}
我不确定 MyServiceBinder 中对 MyService 的引用是否是泄漏的来源。那么我的代码中可能存在泄漏吗?
谢谢和问候
编辑:
private void launchService(boolean isFirst){
if(service == null){
if(isFirst)
startService(new Intent(this, MyService.class);
}
}
如果我“通常”关闭 MyActivity 服务将停止,因此 onServiceDisconnect 在 onDestroy -> unbindService 未被调用之前被调用
编辑2:
我再次进行了一些堆转储并通过 ddms 强制 GC(导致 GC)。我发现 MyService、MyServiceBinder 和 LocalServiceConnection 无法进行垃圾收集,因为它们仍然保留在内存中,而所有其他实例都已被释放。MyService 和 LocalServiceConnection 具有对 MyServiceBinder 对象的动态引用。MyServiceBinder 似乎没有通往 gc 根的路径。问题是为什么这个 Binder 对象没有被垃圾收集???会不会是 MyServiceBinder 引用了 MyService,而后者又引用了 MyServiceBinder?也许-如果确实存在这种循环-因此无法释放 MyServiceBinder 对象?