1,内存泄漏:
一般内存泄漏(traditional memory leak)的原因是:当该对象的所有引用都已经释放了,对象仍未被释放。(译者注:Cursor忘记关闭等)
逻辑内存泄漏(logical memory leak)的原因是:当应用不再需要这个对象,当仍未释放该对象的所有引用。
2,产生内存泄漏原因
(1)将Activity或View等对象定义成静态变量,如果这个静态变量在Activity生命周期结束后没有清空,就导致内存泄漏。因为static变量是贯穿这个应用的生命周期的,所以被泄漏的Activity就会一直存在于应用的进程中,不会被垃圾回收器回收。
public class LeakActivity extends AppCompatActivity {
private static Context sContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_leak);
sContext = this;
}
}
(2)非静态匿名内部类或非静态内部类,内部类的优势之一就是可以访问外部类,不幸的是,导致内存泄漏的原因,就是内部类持有外部类实例的强引用。
最常见的就是Handler的写法:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
(3)context 引用不正确
第三方SDK传this
3,常见解决方案
(1)将内部类定义成静态内部类,并且将外部引用采用弱引用
如Handler的正确写法
private static class MyHandler extends Handler {Thread的正确使用
private WeakReference<MyPresenter> activityWeakReference;
public MyHandler(MyPresenter activity){
activityWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MyPresenter activity = activityWeakReference.get();
if(activity != null) {
}
}
}
public class MainActivity extends Activity {(2)context的正确使用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleTwo();
}
private void exampleTwo() {
new MyThread().start();
}
private static class MyThread extends Thread {
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
}
}
}
}
能传applicationContext的地方就传applicationContext,比如说Toast的就可以传applicationContext;对于第三方SDK也是一样,能传applicationContext就不传this。