나는 최근에 이상한 기억 문제에 부딪쳤다. MyActivity (MyService를 시작 함)를 시작할 때마다 내 앱의 메모리 사용량이 증가합니다. 그래서 MyActivity를 시작하고 끝내고 나서 몇 시간 후에 앱의 메모리가 부족합니다. MyActivity를 두 번 끝내고 마무리 한 후에 힙 덤프를 수행했습니다. 나는 거기에 MyService의 2 인스턴스가 메모리에 있음을 발견했다. >이 $ 0 - 0x42746880Android 서비스 바인더가 누출 되었습니까?
@
COM .....이면 MyService : - 내가 '수신 참조'한 후 '뿌리를 GC하는 경로'> 나는 (두 경우에) 라인을 다음 있어요 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에 대한 참조가 누출의 원인인지 확실하지 않습니다. 그래서 내 코드에 누수가있을 수 있습니까?
들으 & reagards
편집 :
private void launchService(boolean isFirst){
if(service == null){
if(isFirst)
startService(new Intent(this, MyService.class);
}
}
내가 "보통"가까운 MyActivity이 서비스가 중지되고, 따라서 onServiceDisconnect이들의 OnDestroy 전에 호출되는 경우 -> unbindService이
EDIT2 호출되지 않습니다 :
일부 힙 덤프를 다시 작성하고 ddms를 통해 GC를 강제 실행했습니다 (GC 발생). MyService, MyServiceBinder 및 LocalServiceConnection은 가비지 수집을 할 수 없다는 것을 알았습니다. 다른 모든 인스턴스가 해제 된 동안 여전히 메모리에 남아 있기 때문입니다. MyService 및 LocalServiceConnection에는 MyServiceBinder 객체에 대한 실제 참조가 있습니다. MyServiceBinder는 gc 루트에 대한 경로가없는 것 같습니다. 문제는이 바인더 객체가 가비지 수집되지 않는 이유입니다. ??? MyServiceBinder가 MyService를 참조하고 MyServiceBinder가 MyServiceBinder를 참조 할 수 있습니까? 어쩌면 - 그런 종류의 루프가 존재한다면 - MyServiceBinder 객체는 해제 될 수 없습니까? 널 (null)에 대한 onCreate()
검사 서비스에서
launchService() 구현? –
방금 코드를 업데이트하여보다 정확하게 만들었습니다. – user2224350