文章目錄
- 標題:什么是android記憶體泄漏
- 舉例
- 1、單例模式造成記憶體泄漏
- 2、非靜態內部類,匿名內容類造成記憶體泄漏
- 2.1、handler造成記憶體泄露(歸屬第二類)
- 3、資源未關閉造成記憶體泄漏
- 4、WebView造成的記憶體泄漏
- 記憶體泄漏延伸:Java中四種參考型別
- 強軟弱虛
標題:什么是android記憶體泄漏
答: 記憶體泄漏:長生命周期的物件持有短生命周期的物件,導致短生命周期物件不能被回收
舉例
1、單例模式造成記憶體泄漏
原因:
單例模式生命周期比activity生命周期長,單例模式參考了activity的context,,activity退出的時候,導致activity不能被回收
解決辦法:
1、使用 Application 的 context
2、將context的參考方式改為弱參考
代碼舉例
//使用 Application 的 context
public class Singleton {
private static volatile Singleton instance = null;
private Context context;
private Singleton(Context context) {
this.context = context.getApplicationContext();
}
public static Singleton getInstance(Context context) {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(context);
}
}
}
return instance;
}
public void function(String param1, String param2) {
context.startActivity(new Intent(context, MainActivity.class));
}
}
//將context的參考方式改為弱參考
public class SingletonWeakReference {
private static volatile SingletonWeakReference instance = null;
private WeakReference weakReference;
private SingletonWeakReference(Context context) {
weakReference = new WeakReference(context);
}
public static SingletonWeakReference getInstance(Context context) {
if (instance == null) {
synchronized (SingletonWeakReference.class) {
if (instance == null) {
instance = new SingletonWeakReference(context);
}
}
}
return instance;
}
public void function(String param1, String param2) {
Context context = (Context) weakReference.get();
if (context != null) {
context.startActivity(new Intent(context, MainActivity.class));
}
}
}
2、非靜態內部類,匿名內容類造成記憶體泄漏
原因:
非靜態內部類持有外部類的參考,如果外部類的實體已經結束生命周期,但內部類仍然在執行,就會導致外部類不能被回收,
解決辦法:
1、在Activity結束時將反注冊,結束倒計時,清空訊息,等(broadCastReceiver,TimerTask,handler)
2、使用靜態內部類+弱參考
2.1、handler造成記憶體泄露(歸屬第二類)
原因:
a、message被Handler send出去的時候,會被加入的MessageQueue中,Looper會不停的從MessageQueue中取出Message并分發執行,但是如果Activity退出的時候,Handler發送的message沒有執行完畢,那么Handler就不會被回收,但是由于非靜態內部類持有外部類的參考,導致外部類不會被回收
b、handler發送的訊息在handler的訊息佇列中,如果此時activity finish掉,那么訊息佇列的訊息依舊會由handler進行處理
解決辦法:
1、在Activity結束時將Handler里面的Message清空
2、使用靜態內部類+弱參考
代碼舉例
//在Activity結束時將Handler里面的Message清空
@Override
protected void onDestroy() {
super.onDestroy();
//將Handler里面訊息清空
mHandler.removeCallbacksAndMessages(null);
}
//使用靜態內部類+弱參考
private static class MyHandler extends Handler {
private WeakReference weakReference;
private MyHandler(Context context) {
weakReference = new WeakReference(context);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Context context = (Context) weakReference.get();
if (context != null) {
context.startActivity(new Intent(context, MainActivity.class));
}
}
}
3、資源未關閉造成記憶體泄漏
BraodcastReceiver ,Cursor,Bitmap,io流等資源的使用,應該在Activity銷毀時及時關倍訓者注銷,否則這些資源將不會被回收,造成記憶體泄漏,
BraodcastReceiver注銷注冊unregisterReceiver()
io流關閉流InputStream ,OutputStream.close()
資料庫游標Cursor關閉游標cursor.close()
Bitmap呼叫recycle()回收記憶體,再賦為null
4、WebView造成的記憶體泄漏
@Override
protected void onDestroy() {
super.onDestroy();
// 先從父控制元件中移除WebView
mWebViewContainer.removeView(mWebView);
mWebView.stopLoading();
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.removeAllViews();
mWebView.destroy();
}
記憶體泄漏延伸:Java中四種參考型別
強軟弱虛
強參考:即使記憶體不足,JVM寧愿拋出OOM,也不會去回收,
軟參考:當記憶體不足,會觸發JVM的GC,如果GC后,記憶體還是不足,就會把軟參考的包裹的物件回收,也就是只有在記憶體不足,JVM才會回收該物件,
弱參考:只要發生GC,就會被回收
虛參考:
//下面先來看看如何創建一個軟參考:
SoftReference<Student>studentSoftReference=new SoftReference<Student>(new Student());
//軟參考就是把物件用SoftReference包裹一下,當我們需要從軟參考物件獲得包裹的物件,只要get一下就可以了:
SoftReference<Student>studentSoftReference=new SoftReference<Student>(new Student());
Student student = studentSoftReference.get();
System.out.println(student);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/99489.html
標籤:其他
上一篇:PyQt5 API求救
