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

歡迎訪問 生活随笔!

生活随笔

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

Android

android中momery检测,Android性能优化第(二)篇---Memory Monitor检测内存泄露

發布時間:2025/3/17 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android中momery检测,Android性能优化第(二)篇---Memory Monitor检测内存泄露 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文為LooperJing原創文章,轉載請注明出處!

多練習多寫代碼.jpg

上篇說了一些性能優化的理論部分,主要是回顧一下,有了理論,小平同志又講了,實踐是檢驗真理的唯一標準,對于內存泄露的問題,現在通過Android Studio自帶工具Memory Monitor 檢測出來。性能優化的重要性不需要在強調,但是要強調一下,我并不是一個老司機,嘿嘿!沒用過這個工具的,請睜大眼睛。如果你用過,那么就不用在看這篇博客了。

先看一段會發生內存泄露的代碼

public class UserManger {

private static UserManger instance;

private Context context;

private UserManger(Context context) {

this.context = context;

}

public static UserManger getInstance(Context context) {

if (instance == null) {

instance = new UserManger(context);

}

return instance;

}

}

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

UserManger userManger = UserManger.getInstance(this);

}

}

代碼很簡單,就是一個單利模式泄露的場景,我們現在的關心的不是代碼本身,而是如何將代碼里面的內存泄露給找出來。但是對于上面的代碼發生內存泄露的原因還是有必要提一下。

上篇博客說了,內存泄漏產生的原因是:當一個對象已經不需要再使用了,本該被回收時,而有另外一個正在使用的對象持有它的引用從而就導致,對象不能被回收。這種導致了本該被回收的對象不能被回收而停留在堆內存中,就產生了內存泄漏。

在上面的代碼中,發生泄露的不是UserManger,而是MainActivity,UserManger中有一個靜態成員instance,其生命周期和應用程序的生命周期一致,當退出應用時,才能被銷毀,但是當GC準備回收MainActivity時,結果呢MainActivity的對象(this)在被UserManger所引用,UserManger本身又不能被干掉,所以就發生了內存泄露。

monitors.png

Memory Monitor是Android Monitors中的一種,Monitors主要包括四種,Memory Monitor ,CPU Monitor ,NetWork Monitor, GPU Monitor ,今天介紹的是Memory Monitor ,其他的Monitor,在后面也準備講。

Memory Monitor界面

Memory Monitor.png

圖中水平方向是時間軸,豎直方向是內存的分配情況

圖中深藍色的區域,表示當前正在使用中的內存總量,淺藍色或者淺灰色區域,表示空閑內存或者叫作未分配內存。

左上角工具欄三個圓圈按鈕依次代表

GC按鈕 ,可以手動GC,回收程序垃圾

內存快照(Dump Java Heap) ,點擊可以生成一個文件(包名+日期+“.hprof”),可以記錄摸一個時間點內,程序內存的情況

Allocation Traking ,點擊一次開始, 再次點擊結束,也可以可以生成一個文件。

回到我們的程序,多點擊幾次GC,看一下這個應用的內存使用情況。

內存使用情況.jpg

可以看到現在已經分配的內存有19.68M,我把手機旋轉一下,在看。

旋轉后內存使用情況.png

可以看到現在的內存使用量是21.09M,還是一樣的界面,卻多了1.41M!!!這很關鍵。

接下來,我們找一下,哪里發生了泄露。點擊Dump Java Heap,生成快照文件tool.test.memory.memoryleak_2016.11.13_21.38.hprof,Android Studio 自動彈出HPROF Viewer來分析它。

快照文件分析.png

現在介紹一下HPROF Viewer的用法

HPROF Viewer查看方式

左上角兩個紅框,是可選列表, 分別是用來選擇Heap區域, 和Class View的展示方式的.

Heap類型分為:

App Heap -- 當前App使用的Heap

Image Heap -- 磁盤上當前App的內存映射拷貝

Zygote Heap -- Zygote進程Heap(每個App進程都是從Zygote孵化出來的, 這部分基本是framework中的通用的類的Heap)

Class List View -- 類列表方式

Package Tree View -- 根據包結構的樹狀顯示

我通常點擊App heap下面的Classs Name把Heap中所有類按照字母順序排序,然后按照字母順序查找。

HPROF Viewer主要分ABC三大板塊

板塊A:這個應用中所有類的名字

版塊B:左邊類的所有實例

板塊C:在選擇B中的實例后,這個實例的引用樹

A板塊左上角列名解釋

列名

解釋

Class Name

類名,Heap中的所有Class

Total Count

內存中該類這個對象總共的數量,有的在棧中,有的在堆中

Heap Count

堆內存中這個類 對象的個數

Sizeof

每個該實例占用的內存大小

Shallow Size

所有該類的實例占用的內存大小

Retained Size

所有該類對象被釋放掉,會釋放多少內存

B板塊右上角上角列名解釋

列名

解釋

Instance

該類的實例

Depth

深度, 從任一GC Root點到該實例的最短跳數

Dominating Size

該實例可支配的內存大小

B板塊右上角有個"的按鈕, 點擊會進入HPROF Analyzer的hprof的分析界面:

Analyzer Tasks.png

"

在這個界面中可以直接把內存泄露可能的類找出來。

下面分析一下MainActivity的泄露情況

MainActivity發生內存泄露.png

一個Activity應該只有一個實例,但是從A區域來看 total count的值為2,heap count的值也為2,說明有一個是多余的。

在B區域中可以看見兩個MainActivity的實例,點擊一個看他的引用樹情況

在C區域中可以看到MainActivity的實例Context被UserManger的 instance引用了,引用深度為1.

在Analyzer Tasks 區域中,直接告訴你Leaked Activities,MainActivity包含其中

多方面的證據表明MainActivity發生了內存泄露

解決方案

public class UserManger {

private static UserManger instance;

private Context context;

private UserManger(Context context) {

this.context = context;

}

public static UserManger getInstance(Context context) {

if (instance == null) {

if(context!=null){

instance = new UserManger(context.getApplicationContext());

}

}

return instance;

}

}

不要用Activity的Context,因為Activity隨時可能被回收,我們用Application的Context,Application的Context的生命周期是整個應用,不回收也沒有關系。

Memory Monitor獲得內存的動態視圖,Heap Viewer顯示堆內存中存儲了什么,可惜Heap Viewer不能顯示你的數據具體分配在代碼的何處,如果還不過癮,想知道具體是哪些代碼使用了內存,還有一個功能是Allocation Tracker,用來內存分配追蹤。在內存圖中點擊途中標紅的部分,啟動追蹤,再次點擊就是停止追蹤,隨后自動生成一個alloc結尾的文件,這個文件就記錄了這次追蹤到的所有數據,然后會在右上角打開一個數據面板

Allocation Tracker啟動追蹤

Allocation Tracker啟動追蹤.png,

Allocation Tracker查看方式

Allocation Tracker查看方式

有兩種查看方式,默認是Group by Method方式

Group by Method:用方法來分類我們的內存分配

Group by Allocator:用內存分配器來分類我們的內存分配

從上圖可以看出,首先以線程對象分類,Size是內存大小,Count是分配了多少次內存,點擊一下線程就會查看每個線程里所有分配內存的方法

Group by Method方式

每個線程里所有分配內存的方法.png

OK,-Memory Monitor

** Group by Allocator方式**

EY%HY_B74%BUE22C6$G~CTP.png

右鍵可以直接跳到源碼

- 扇形統計圖

AQFHT$@7TYP0S_1`DU@%S%6.png

點擊統計圖按鈕,會生成上圖,扇形統計圖是以圓心為起點,最外層是其內存實際分配的對象,每一個同心圓可能被分割成多個部分,代表了其不同的子孫,每一個同心圓代表他的一個后代,每個分割的部分代表了某一帶人有多人,你雙擊某個同心圓中某個分割的部分,會變成以你點擊的那一代為圓心再向外展開。

除了扇形圖,還有柱狀圖可選擇,可以自己操作,OK,Memory Monitor到此結束,下一篇性能優化部分博客仍然是檢測內存泄露,明天上班,晚安!

總結

以上是生活随笔為你收集整理的android中momery检测,Android性能优化第(二)篇---Memory Monitor检测内存泄露的全部內容,希望文章能夠幫你解決所遇到的問題。

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