日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android leak内存,GitHub - jin870132/memoryleakdemo: 安卓内存泄露几种常见形式及解决方案...

發布時間:2025/3/12 Android 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android leak内存,GitHub - jin870132/memoryleakdemo: 安卓内存泄露几种常见形式及解决方案... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

安卓內存泄露幾種常見形式及解決方案

一.前言

1.內存溢出與內存泄露

內存溢出(oom),是指程序在申請內存時,沒有足夠的內存空間供其使用,出現oom;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。

內存泄露 (memory leak),是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。

memory leak會最終會導致oom!

二.內存泄露的幾種形式

1.匿名內部類的使用

a.Thread內存泄漏

這里最常見的形式就是使用new thread開啟一個子線程.

子線程會對當前activity有一個隱式的強引用

當activity退出時候,如果子線程還在運行activity就不會釋放.

running = true;

new Thread(new Runnable() {

@Override

public void run() {

while (running) {

SystemClock.sleep(1000);

runOnUiThread(new Runnable() {

@Override

public void run() {

SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

String date = sDateFormat.format(new Date());

tv.setText(date);

}

});

}

}

}).start();

LeakCanary檢測結果

解決辦法:

調用onDestroy后結束子線程

@Override

protected void onDestroy() {

super.onDestroy();

running = false;

}

b.Timer內存泄露

這里既然thread使用有問題,那么我們用hander+Timer的形式可以嗎,我們來看看.

結果抱歉,使用Timer和Thread無論從原理還是結果上都與handler一樣.

public class HandlerAndTimerErr extends AppCompatActivity {

Handler mhandler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

tv.setText(msg.obj.toString());

}

};

private TextView tv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_thread_err);

tv = (TextView) findViewById(R.id.tv);

Timer timer = new Timer();

timer.scheduleAtFixedRate(new TimerTask() {

@Override

public void run() {

SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

String date = sDateFormat.format(new Date());

Message message = new Message();

message.obj=date;

mhandler.sendMessage(message);

}

}, 1, 1000);

}

}

LeakCanary檢測結果

解決辦法

@Override

protected void onDestroy() {

super.onDestroy();

timer.cancel();

}

2.純handler的錯誤使用

如果僅使用handler還可以這樣寫

public class HandlerErr extends AppCompatActivity {

Handler mhandler = new Handler();

private TextView tv;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_thread_err);

tv = (TextView) findViewById(R.id.tv);

mhandler.postDelayed(new Runnable() {

@Override

public void run() {

SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

String date = sDateFormat.format(new Date());

tv.setText(date);

mhandler.postDelayed(this,1000);

}

},1000);

}

}

LeakCanary檢測結果

解決辦法

@Override

protected void onDestroy() {

super.onDestroy();

//移除當前handler發送的請求

mhandler.removeCallbacksAndMessages(null);

}

3.context導致內存泄露

做一個單例的ToastUtils來顯示toast是很多人會做的.你的ToastUtils是否這么寫的?

public class ToastUtils {

private static Toast toast;

public static void ShowToast(Context context, String text){

if (toast==null) {

toast = Toast.makeText(context, text, Toast.LENGTH_LONG);

}else{

toast.setText(text);

}

toast.show();

}

}

這樣寫其實有很大問題:

如果此時傳入的是 Activity 的 Context,當這個 Context 所對應的 Activity 退出時,由于該 Context 的引用被單例對象所持有,其生命周期等于整個應用程序的生命周期,所以當前 Activity退出時它的內存并不會被回收,這就造成泄漏了。

LeakCanary檢測結果

解決辦法:

1.使用ApplicationContext代替Activity的Context

2.如果必須要Activity的Context請換種寫法吧,哈哈.

4.leackCannary使用

leackCannary使用其實非常簡單

githup鏈接: https://github.com/square/leakcanary

1.首先在你的build.gradle添加引用:

dependencies {

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'

releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'

testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'

}

2.在你的application中初始化

LeakCanary.install(this);

3.提醒

這里其實就已經配置完成可以運行使用了.

注意,當你進入一個activity再退出之后等個三五秒如果有溢出就會提示的.

4.講解

我們就拿這個例子來說

這個是告訴我們 ToastUtils下面有一個靜態成員變量toast

它引用了一個context

這個context是ContextErr這個activity的一個實例(instance)

它導致了內存泄露.

5.源碼地址

總結

以上是生活随笔為你收集整理的Android leak内存,GitHub - jin870132/memoryleakdemo: 安卓内存泄露几种常见形式及解决方案...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。