内存泄露情况:
1:使用单例导致内存泄露
public class Singleton {
private static Singleton singleton=null;
private Context context;
public Singleton(Context context) {
this.context=context;
}
public static Singleton getSingleton(Context context) {
if (null == singleton) {
singleton=new Singleton(context);
}
return singleton;
}
}
原因:静态的单例使它的生命周期与应用的生命周期一样长,context一般传的是Activity或者Service等上下文,如果退出Activity,activity就没有用了,但是静态单例还会持有Activity的引用,导致无法回收,导致内存泄露。
2.WebView造成的内存泄露
原因:webview加载网页后会长期占用内存而不能释放
处理:在activity的destory()时销毁它,释放内存
@Override
protected void onDestroy() {
super.onDestroy();
rl_root.removeView(mWebView);
mWebView.clearHistory();
mWebView.removeAllViews();
}
3.动画造成的内存泄露
原因:activity在销毁的时候没有调用cancel方法,动画引用控件,控件引用activity,所以activity无法正常释放
处理:在activity的destory()时销毁它,释放内存
@Override
protected void onDestroy() {
super.onDestroy();
mAnimator.cancel();
}
4.资源未关闭导致内存泄露
处理:使用IO,Cursor后,关闭。
OutputStream out = null;
try {
out = new FileOutputStream("");
// 自己操作
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Cursor cursor = null;
try{
cursor = mContext.getContentResolver().query(uri,null,null,null,null);
if(cursor != null){
cursor.moveToFirst();
//自己处理
}
}catch(Exception e){
e.printStatckTrace();
}finally{
if(cursor != null){
cursor.close();
}
}
5. 注册广播,未关闭,操作内存泄露
处理:在activity的destory()时销毁它,释放内存
@Override
protected void onDestroy() {
super.onDestroy();
if(mReceiver != null){
this.unregisterRecevier(mReceiver);
}
}
6.非静态内部类导致内存泄露,比如handler
原因1:activity关闭了,handle的MessageQuue消队列里还有下次没有消息处理或者正在处理,导致activity无法回收。
处理:使用静态内部类加弱引用
public class ClassModelActivity extends Activity {
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityclassmodel);
mHandler=new WeekHandler(this);
}
private static class WeekHandler extends Handler{
private WeakReference<ClassModelActivity > weekActivity;
public WeekHandler(ClassModelActivity activity) {
weekActivity=new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ClassModelActivity activity=weekActivity.get();
if(activity != null){
switch (msg.what){
}
}
}
}
上面可以避免actiity内存泄露,但是messageQueue消息队列中可能还有消息消息,所以也将它清理调掉
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
}
7.匿名内部类对象导致activit不能被回收
原因:直接new线程或者new AsyncTask,匿名内部类对象默认隐式持有activity对象的引用
处理:像上面一样使用静态内部类加弱引用的方式。
8. Timer和TimerTask导致内存泄露
原因:activity关闭时,Timer还在等待执行TimerTask,它持有activity对象,导致activity不能被回收
处理:activity销毁时,调用Timer和TimerTask的cancel方法。
@Override
protected void onDestroy() {
super.onDestroy();
mTime.cancel();
mTimerTask.cancel();
}