1、单例和工具类造成的内存泄漏
单例是造成内存泄漏最常见的一种形式,单例对象的生命周期与Application一样长,当单例对象持有activity的引用的时候,activity销毁时候本该被内存回收,却无法回收,这就造成了内存泄漏。
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
解决办法: 将持有的context对象改为全局的ApplicationContext引用
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context.getApplicationContext();
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
2、内部类造成的内存泄漏
非静态内部类会隐式持有外部类的引用。那么很常见的一类就是Handler和AsyncTask造成的内存泄漏了
比如,Handler的常见写法:
public class MainActivity extends AppCompatActivity {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//...
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
}
private void loadData(){
//...request
Message message = Message.obtain();
mHandler.sendMessage(message);
}
}
这时候如果Activity该销毁了而handler里面还有任务未执行完毕,就会造成内存泄漏。
解决办法:将其改为Handler持有activity的弱引用
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private Handler mHandler = new MainHandler(this);
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv);
mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.sendMessage(Message.obtain());
}
});
}
class MainHandler extends Handler {
private WeakReference<MainActivity> wrf;
public MainHandler(MainActivity mainActivity) {
wrf = new WeakReference<MainActivity>(mainActivity);
}
@Override
public void handleMessage(Message msg) {
MainActivity mainActivity = wrf.get();
mainActivity.mTextView.setText("jack is handsome");
}
}
}
同理AsynTask也会造成一样的内存泄漏,解决办法跟Handler一样。
3、数据库,文件流等使用完未及时关闭。
对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的代码,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。
4、监听器没有注销造成的内存泄漏
在Android程序里面存在很多需要register与unregister的监听器,我们需要确保及时unregister监听器。
感谢博主:https://blog.csdn.net/qq_35373333/article/details/74909811