内存问题
- 内存泄露 (对象不被回收,一直占据着内存,反复内存泄露将引发内存溢出)
- 内存溢出 OOM(内存不够用)
垃圾回收
如何判定是垃圾
- 引用计数法(可能存在互相引用无法被回收)
- 可达性分析(从各个GCROOT 出发,如果无法被找到的对象就会被回收)
handler 内存泄露
此处 handler 对象为内部类,非静态内部类和匿名内部类能够调用外部类的属性,因此该内部类实际上持有外部类的引用。此时如果 Activity 生命周期结束需要被回收,但是handler这个匿名内部类仍然持有Activity引用导致回收失败
解决方式
- 定义静态内部类 handler,同时持有外部类的弱引用, 弱引用不会阻止 gc 回收。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_static_handler);
initView();
}
private void initView() {
mStateTv = findViewById(R.id.tv_state);
}
private static class MyHandler extends Handler {
private final WeakReference<StaticHandlerActivity> mActivity;
public MyHandler(StaticHandlerActivity activity) {
mActivity = new WeakReference<StaticHandlerActivity>(activity); //获取弱引用Activity对象
}
@Override
public void handleMessage(@NonNull Message msg) {
if (mActivity.get() != null) {
//TODO
//利用弱引用来获取UI控件,不会对回收造成影响
mActivity.get().mStateTv.setText("state change");
//如果直接new Activity()来获取Activity属于强引用,依然会造成内存泄漏
//new StaticHandlerActivity().mStateTv.setText("state change");
}
}
}
}