内存泄露在Android开发中很常见,每次产品上线之前都要集中解决内存泄露问题,有的问题很明显,有的藏的很深,解决起来要颇费一番功夫,不过总的思路都是一样,就是切断引用链,让资源在该释放的时候能被及时释放。
我们先看一个内存泄露的案例:
public class ServiceManager {
public static void bindService(final BindResponse response) {
Context context = MyApplication.getInstance();
Intent intent = new Intent(context, MyService.class);
context.bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
response.onServiceBinded();
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
response.onServiceUnbinded();
}
}, Context.BIND_AUTO_CREATE);
}
}
这是个很典型的服务绑定,传入了一个回调,在服务绑定和解绑时调用这个回调。乍一看不会有什么问题,其实会有内存泄露的风险。我们看Activity中如何调用的,如下:
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ServiceManager.bindService(new BindResponse() {
@Override
public void onServiceBinded() {
// TODO Auto-generated method stub
}
@Override
public void onServiceUnbinded() {
// TODO Auto-generated method stub
}
});
}
}
这里简单得不能再简单了,但是会让这个Activity有内存泄露,资源被某个无形的手长期持有而不能释放。我们现在就来给这只背后的手揪出来,导出内存用MAT查看,如下:
可以看到这里Activity被ServiceManager持有,然后一路转手到mLoadedApk,最后BOSS