欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

AndroidStudio+MAT如何解決內存泄漏

小編給大家分享一下Android Studio+MAT如何解決內存泄漏,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)公司專注于善右網(wǎng)站建設服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供善右營銷型網(wǎng)站建設,善右網(wǎng)站制作、善右網(wǎng)頁設計、善右網(wǎng)站官網(wǎng)定制、小程序設計服務,打造善右網(wǎng)絡公司原創(chuàng)品牌,更為您提供善右網(wǎng)站排名全網(wǎng)營銷落地服務。

首先什么是內存泄漏?

內存泄漏就是一些已經(jīng)不使用的對象還存在于內存之中且垃圾回收機制無法回收它們,導致它們常駐內存,會使內存消耗越來越大,最終導致程序性能變差。
其中在Android虛擬機中采用的是根節(jié)點搜索算法枚舉根節(jié)點判斷是否是垃圾,虛擬機會從GC Roots開始遍歷,如果一個節(jié)點找不到一條到達GC Roots的路線,也就是沒和GC Roots 相連,那么就證明該引用無效,可以被回收,內存泄漏就是存在一些不好的調用導致一些無用對象和GC Roots相連,無法被回收。

既然知道了什么是內存泄漏,自然就知道如何去避免了,就是我們在寫代碼的時候盡量注意產(chǎn)生對無用對象長時間的引用,說起來簡單,但是需要足夠的經(jīng)驗才能達到,所以內存泄漏還是比較容易出現(xiàn)的,既然不容易完全避免,那么我們就要能發(fā)現(xiàn)程序中出現(xiàn)的內存泄漏并修復它,
下面我就說說如何發(fā)現(xiàn)內存泄漏的吧。

查找內存泄漏:

比如說下面這個代碼:

public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String string = new String();
  }
  public void click(View view){
    Intent intent = new Intent();
    intent.setClass(getApplicationContext(),SecondActivity.class);
    startActivity(intent);
  }
}
public class SecondActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(8000000L);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
    new Thread(runnable).start();
  }
}

每次跳轉到這個Activity中時都會調用一個線程,然后這個線程會執(zhí)行runnable的run方法 由于Runnable是一個匿名內部對象 所以握有SecondActivity的引用,因此很簡單的兩個Activity,可由MainActivity跳轉到SecondActivity中,下面我們從MainActivity跳到SecondActivity 然后從SecondActivity返回MainActivity,連續(xù)這樣5次 ,最終返回MainActivity,按照常理來說,我們從SecondActivity返回MainActivity之后 SecondActivity就該被銷毀回收,可實際可能并不是這樣。

這時候要判斷發(fā)沒發(fā)生內存溢出就要使用工具了!下面有兩種方式

1.利用MAT工具查找

首先打開AS中的Android Device Monitor工具 具體位置如下圖:

Android Studio+MAT如何解決內存泄漏

打開后會出現(xiàn)如下的界面

Android Studio+MAT如何解決內存泄漏

先選中你要檢測的應用的包名,然后點擊下圖畫圈的地方,會在程序包名后標記一個圖標

Android Studio+MAT如何解決內存泄漏

接下來要做的就是操作我們的app 來回跳轉5次。

之后點擊下圖的圖標 就可導出hprof文件進行分析了

Android Studio+MAT如何解決內存泄漏

導出文件如下圖所示:

Android Studio+MAT如何解決內存泄漏

得到了hprof文件 我們就可以利用MAT工具進行分析了,

打開MAT工具

如果沒有 可以在下面網(wǎng)址下載

MAT工具下載地址

Android Studio+MAT如何解決內存泄漏

界面如下圖所示:

Android Studio+MAT如何解決內存泄漏

打開我們先前導出的hprof文件 ,不出意外會報下面的錯誤

Android Studio+MAT如何解決內存泄漏

這是因為MAT是用來分析java程序的hprof文件的 與Android導出的hprof有一定的格式區(qū)別,因此我們需要把導出的hprof文件轉換一下,sdk中提供給我們轉換的工具 hprof-conv.exe 在下圖的位置

Android Studio+MAT如何解決內存泄漏

接下來我們cd到這個路徑下執(zhí)行這個命令轉換我們的hprof文件即可,如下圖

Android Studio+MAT如何解決內存泄漏

其中 hprof-conv 命令 這樣使用

hprof-conv 源文件 輸出文件

比如 hprof-conv E:\aaa.hprof E:\output.hprof

就是 把aaa.hprof 轉換為output.hprof輸出 output.hprof就是我們轉換之后的文件,圖中 mat2.hprof就是我們轉換完的文件。

接下來 我們用MAT工具打開轉換之后的mat2.hprof文件即可 ,打開后不報錯 如下圖所示:

Android Studio+MAT如何解決內存泄漏

之后我們就可以查看當前內存中存在的對象了,由于我們內存泄漏一般發(fā)生在Activity中,因此只需要查找Activity即可。

點擊下圖中標記的QQL圖標 輸入 select * from instanceof android.app.Activity

類似于 SQL語句 查找 Activity相關的信息 點擊 紅色嘆號執(zhí)行后 如下圖所示:

Android Studio+MAT如何解決內存泄漏

接下來 我們就可以看到下面過濾到的Activity信息了

如上圖所示, 其中內存中還存在 6個SecondActivity實例,但是我們是想要全部退出的,這表明出現(xiàn)了內存泄漏

其中 有 Shallow size 和 Retained Size兩個屬性

Shallow Size
對象自身占用的內存大小,不包括它引用的對象。針對非數(shù)組類型的對象,它的大小就是對象與它所有的成員變量大小的總和。
當然這里面還會包括一些java語言特性的數(shù)據(jù)存儲單元。針對數(shù)組類型的對象,它的大小是數(shù)組元素對象的大小總和。
Retained Size
Retained Size=當前對象大小+當前對象可直接或間接引用到的對象的大小總和。(間接引用的含義:A->B->C, C就是間接引用)
不過,釋放的時候還要排除被GC Roots直接或間接引用的對象。他們暫時不會被被當做Garbage。

接下來 右擊一個SecondActivity

Android Studio+MAT如何解決內存泄漏

選擇 with all references

打開如下圖所示的頁面

Android Studio+MAT如何解決內存泄漏

查看下圖的頁面

看到 this0引用了這個Activitythis0是表示 內部類的意思,也就是一個內部類引用了Activity 而 this$0又被 target引用 target是一個線程,原因找到了,內存泄漏的原因 就是 Activity被 內部類引用 而內部類又被線程使用 因此無法釋放,我們轉到這個類的代碼處查看

public class SecondActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(8000000L);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
    new Thread(runnable).start();
  }
}
確實 在

確實 在 SecondActivity中 存在Runnable 內部類對象,然后又被線程 使用,而線程要執(zhí)行8000秒 因此 SecondActivity對象被引用 無法釋放,導致了內存溢出。

要解決這種的內存溢出,要及時在Activity退出時結束線程(不過不大好結束。。),或者良好的控制線程執(zhí)行的時間即可。

這樣我們就找出了這個程序中的內存溢出。

2.直接利用Android Studio的 Monitor Memory 查找內存溢出

還是利用上面那個程序,我就簡單點說了。

首先 在手機上運行程序,打開AS的 Minotor 界面 查看Memory 圖像

Android Studio+MAT如何解決內存泄漏

點擊 小卡車圖標(圖中1位置圖標) 可以觸發(fā)一次 GC

Android Studio+MAT如何解決內存泄漏

點擊 圖中2位置圖標可以查看hprof文件

Android Studio+MAT如何解決內存泄漏

左邊是 內存中的對象,在里面找 Activity 看存不存在我們希望已經(jīng)回收的Activity 如果 出現(xiàn)我們期望已經(jīng)回收的Activity,單擊 就會在右邊顯示它的總的個數(shù),點擊右邊的某個,可以顯示 它的GC Roots的樹關系圖 ,查看關系圖就可以找出發(fā)生內存泄漏的位置(類似于第一種方式)

這樣就完成了內存泄漏的查找。

其中內存泄漏產(chǎn)生的原因在Android中大致分為以下幾種:

1.static變量引起的內存泄漏

因為static變量的生命周期是在類加載時開始 類卸載時結束,也就是說static變量是在程序進程死亡時才釋放,如果在static變量中 引用了Activity 那么 這個Activity由于被引用,便會隨static變量的生命周期一樣,一直無法被釋放,造成內存泄漏。

解決辦法:

在Activity被靜態(tài)變量引用時,使用 getApplicationContext 因為Application生命周期從程序開始到結束,和static變量的一樣。

2.線程造成的內存泄漏

類似于上述例子中的情況,線程執(zhí)行時間很長,及時Activity跳出還會執(zhí)行,因為線程或者Runnable是Acticvity內部類,因此握有Activity的實例(因為創(chuàng)建內部類必須依靠外部類),因此造成Activity無法釋放。

AsyncTask 有線程池,問題更嚴重

解決辦法:

1.合理安排線程執(zhí)行的時間,控制線程在Activity結束前結束。

2.將內部類改為靜態(tài)內部類,并使用弱引用WeakReference來保存Activity實例 因為弱引用 只要GC發(fā)現(xiàn)了 就會回收它 ,因此可盡快回收

3.BitMap占用過多內存

bitmap的解析需要占用內存,但是內存只提供8M的空間給BitMap,如果圖片過多,并且沒有及時 recycle bitmap 那么就會造成內存溢出。

解決辦法:

及時recycle 壓縮圖片之后加載圖片

4.資源未被及時關閉造成的內存泄漏

比如一些Cursor 沒有及時close 會保存有Activity的引用,導致內存泄漏

解決辦法:

在onDestory方法中及時 close即可

5.Handler的使用造成的內存泄漏

由于在Handler的使用中,handler會發(fā)送message對象到 MessageQueue中 然后 Looper會輪詢MessageQueue 然后取出Message執(zhí)行,但是如果一個Message長時間沒被取出執(zhí)行,那么由于 Message中有 Handler的引用,而 Handler 一般來說也是內部類對象,Message引用 Handler ,Handler引用 Activity 這樣 使得 Activity無法回收。

解決辦法:

依舊使用 靜態(tài)內部類+弱引用的方式 可解決

其中還有一些關于 集合對象沒移除,注冊的對象沒反注冊,代碼壓力的問題也可能產(chǎn)生內存泄漏,但是使用上述的幾種解決辦法一般都是可以解決的。

以上是“Android Studio+MAT如何解決內存泄漏”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當前文章:AndroidStudio+MAT如何解決內存泄漏
本文路徑:http://chinadenli.net/article38/jeigpp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、域名注冊、微信公眾號、面包屑導航用戶體驗、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
一区二区不卡免费观看免费| 俄罗斯胖女人性生活视频| 青青草草免费在线视频| 亚洲高清中文字幕一区二区三区| 国产精品一区二区不卡中文 | 亚洲中文字幕高清乱码毛片| 国产免费操美女逼视频| 精品老司机视频在线观看| 91人妻人人做人碰人人九色| 欧美熟妇喷浆一区二区| 在线免费国产一区二区三区| 麻豆剧果冻传媒一二三区| 国产又粗又深又猛又爽又黄| 国产一二三区不卡视频| 日韩一区二区三区观看| 欧美日韩一区二区综合| 亚洲熟妇av一区二区三区色堂| 国产精品日韩精品一区| 日本精品最新字幕视频播放| 婷婷激情四射在线观看视频| 日本99精品在线观看| 欧美在线视频一区观看| 国内午夜精品视频在线观看| 冬爱琴音一区二区中文字幕| 伊人欧美一区二区三区| 91人妻人人做人碰人人九色| 日韩欧美精品一区二区三区 | 日韩欧美一区二区黄色| 亚洲免费视频中文字幕在线观看| 麻豆欧美精品国产综合久久| 亚洲欧美精品伊人久久| 日本精品中文字幕在线视频| 日本免费一区二区三女| 大香蕉伊人一区二区三区| 麻豆果冻传媒一二三区| 中文字幕不卡欧美在线| 日韩精品一区二区毛片| 九九热这里只有免费精品| 国产成人精品视频一区二区三区| 国产福利在线播放麻豆| 伊人天堂午夜精品草草网|