Android内存检测工具
什么是內(nèi)存泄漏?
在運(yùn)行的程序中,如果一個(gè)無(wú)法訪問(wèn)的對(duì)象仍然占用著內(nèi)存空間,即為此對(duì)象造成了內(nèi)存泄漏
垃圾回收(GC)機(jī)制:
當(dāng)垃圾回收運(yùn)行時(shí),虛擬機(jī)首先會(huì)識(shí)別GC Root。GC Root 是一個(gè)可以從堆外部訪問(wèn)的對(duì)象,它可以是本地變量或運(yùn)行中的線(xiàn)程等。虛擬機(jī)會(huì)識(shí)別所有可以從GC Root訪問(wèn)的對(duì)象,它們將會(huì)被保留,而其他無(wú)法從GC Root訪問(wèn)的對(duì)象,則會(huì)被認(rèn)為垃圾并回收掉。
一、通過(guò)Memory Profiler檢測(cè)內(nèi)存泄漏
打開(kāi) Memory Profiler,選中MEMORY ,進(jìn)入MEMORY視圖,
點(diǎn)擊下圖所示按鈕,保存Heap Dump:
1.1、Activity 和 Fragment 內(nèi)存泄漏檢測(cè)
Heap Dump 加載完成后,勾選 “Activity/Fragment Leaks” 選框:
此時(shí)如果有檢查到 Activity 或 Fragment 的泄漏,就會(huì)在界面中顯示出來(lái):
需要注意的是:
針對(duì) Fragment 有個(gè)特別的情況: 如果您載入的 Heap Dump 的時(shí)機(jī),剛好介于 Fragment 被創(chuàng)建和被使用的時(shí)間之間,就會(huì)造成 Memory Profiler 誤報(bào);相同情況也會(huì)發(fā)生在 Fragment 被緩存但是沒(méi)有被復(fù)用的時(shí)候
1.2、通過(guò)包名篩選來(lái)查看APP內(nèi)其他內(nèi)存泄漏的地方
選擇Arrange by package :選擇對(duì)應(yīng)包名,查看可能存在內(nèi)存泄漏的地方
① :選擇包名篩選
② :點(diǎn)擊LeakTestActivity$1 查看LeakedActivity內(nèi)存泄漏的地方
③ :右鍵,跳轉(zhuǎn)到發(fā)生內(nèi)存泄漏源碼的地方
1.3、通過(guò)觀察 MEMORY 內(nèi)存圖標(biāo)趨勢(shì)判斷是否發(fā)生內(nèi)存泄漏
可以通過(guò)橫豎屏切換,或者多執(zhí)行幾次可能發(fā)生內(nèi)存泄漏的代碼,通過(guò)觀察MEMORY 軌跡趨勢(shì),如果內(nèi)存走向是增加的,則肯定發(fā)生了內(nèi)存泄漏,如下圖:
查看堆和內(nèi)存分配:
https://developer.android.com/studio/profile/memory-profiler?utm_source=android-studio#capture-heap-dump
二、HeapView 使用
啟動(dòng):Sdk/tools/monitor 啟動(dòng)Monitor。端口沖突的話(huà)可以先關(guān)閉AS
A:打開(kāi)DDMS視圖,
B:選擇Heap窗口
C:選擇對(duì)應(yīng)包名,點(diǎn)擊Heap 按鈕
D:點(diǎn)擊Heap按鈕
E:Cause GC 更新數(shù)據(jù)
| Heap Size | 堆棧分配給App的內(nèi)存大小 |
| Allocated | 已分配使用的內(nèi)存大小 |
| Free | 空閑的內(nèi)存大小 |
| %Used | Allocated/Heap Size,使用率 |
| Objects | 對(duì)象數(shù)量 |
內(nèi)存詳情
| free | 空閑的對(duì)象 |
| data object | 數(shù)據(jù)對(duì)象,類(lèi)類(lèi)型對(duì)象,最主要的觀察對(duì)象 |
| class object | 類(lèi)類(lèi)型的引用對(duì)象 |
| 1-byte array(byte[],boolean[]) | 一個(gè)字節(jié)的數(shù)組對(duì)象 |
| non-Java object | 非Java對(duì)象 |
每一列含義:
| Count | 數(shù)量 |
| Total Size | 總共占用的內(nèi)存大小 |
| Smallest | 將對(duì)象占用內(nèi)存的大小從小往大排,排在第一個(gè)的對(duì)象占用內(nèi)存大小 |
| Largest | 將對(duì)象占用內(nèi)存的大小從小往大排,排在最后一個(gè)的對(duì)象占用的內(nèi)存大小 |
| Median | 將對(duì)象占用內(nèi)存的大小從小往大排,拍在中間的對(duì)象占用的內(nèi)存大小 |
| Average | 平均值 |
點(diǎn)擊data object行時(shí),可以看到如下的柱狀圖
橫坐標(biāo)是對(duì)象的內(nèi)存大小,這些值隨著不同對(duì)象是不同的,縱坐標(biāo)是在某個(gè)內(nèi)存大小上的對(duì)象的數(shù)量
2.1 HeapView使用場(chǎng)景:
Heap Viewer中的數(shù)值會(huì)自動(dòng)在每次發(fā)生GC時(shí)會(huì)自動(dòng)更新。
2.2 內(nèi)存泄漏檢查
在需要檢測(cè)的用例執(zhí)行后,手動(dòng)點(diǎn)擊 按鈕,觸發(fā)GC,然后觀察 data object 一欄的 Total Size (也可以觀察Heap Size/Allocated內(nèi)存的情況) ,看看內(nèi)存會(huì)不會(huì)恢復(fù)到一個(gè)穩(wěn)定的值,多次操作后,只要這個(gè)值穩(wěn)定,說(shuō)明沒(méi)有內(nèi)存泄漏。
如果每次GC后值都在增長(zhǎng),則說(shuō)明有內(nèi)存泄漏的可能性
2.3 內(nèi)存抖動(dòng)檢查
內(nèi)存抖動(dòng)會(huì)伴隨著頻繁的GC。只需要開(kāi)啟Heap View,觀察數(shù)據(jù)就行了。
如果發(fā)生內(nèi)存抖動(dòng),會(huì)發(fā)現(xiàn)數(shù)據(jù)在短時(shí)間內(nèi)頻繁更新
此部分參考:https://blog.csdn.net/zhangfei2018/article/details/49154479
三、LeakCanary檢查內(nèi)存泄漏
添加依賴(lài):
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4' releaseImplementation'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'Application中初始化:
這樣就能檢測(cè)Activity的內(nèi)存泄漏了,當(dāng)然Fragment或者其他的內(nèi)存泄漏是檢測(cè)不到的。
如果需要檢查Fragment內(nèi)存泄漏,需要使用RefWatcher來(lái)監(jiān)控,修改如下:
在Application中提供一個(gè)全局的RefWatcher 對(duì)象,然后在Fragment調(diào)用如下:
更多內(nèi)存分析方式:
dump文件分析、MAT分析
崩潰檢測(cè)
Monkey 檢測(cè)ANR和Crash
總結(jié)
以上是生活随笔為你收集整理的Android内存检测工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C/C++内存检测工具valgrind
- 下一篇: 内存错误检测工具——kfence工作原理