1、引入庫
2、操作APP,分析結果
3、如果是復雜的問題可以導出hprof文件到android studio 中繼續分析
官方地址:
GitHub - square/leakcanary: A memory leak detection library for Android and Java.
https://github.com/square/leakcanary
#####1、引入庫
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
// Optional, if you use support library fragments:
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.1'
1
2
3
4
#####2、初始化
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
return;
}
LeakCanary.install(this);
}
}
1
2
3
4
5
6
7
8
9
10
11
為了分析內存泄漏,我們寫一個簡單的單例泄漏的例子:
public class TestManager {
private static TestManager manager;
private Context context;
private TestManager(Context context) {
this.context = context;
}
/**
* 如果傳入的context是activity,service的上下文,會導致內存泄漏
* 原因是我們的manger是一個static的靜態對象,這個對象的生命周期和整個app的生命周期一樣長
* 當activity銷毀的時候,我們的這個manger仍然持有者這個activity的context,就會導致activity對象無法被釋放回收,就導致了內存泄漏
*/
public static TestManager getInstance(Context context) {
if (manager == null) {
manager = new TestManager(context);
}
return manager;
}
//正確寫法
public static TestManager getInstanceSafe(Context context) {
if (manager == null) {
manager = new TestManager(context.getApplicationContext());
}
return manager;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
然后寫兩個activity,第一個MainActivity跳轉到第二個SecondActivity,然后SecondActivity使用有內存泄漏的單例。
public class MainActivity extends AppCompatActivity {
private Button btnJump;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnJump = findViewById(R.id.btn_jump);
btnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
}
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TestManager manager = TestManager.getInstance(this);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
我們啟動app,當檢測到內存泄漏的時候,會出現一個彈窗,然后手機桌面會出現一個Leaks的圖標
leaks
點擊即可看到內存泄漏的原因:
leaks
我們這個內存泄漏的例子比較簡單,可以很明顯的看出泄漏的原因
有時候我們會遇到比較復雜的內存泄漏情況,這個時候我們可能需要分析一下hprof文件。
我們打開view->Tool Windows->Device File explorer
hprof
然后在一堆目錄里找到我們的leaks生成的hprof文件:
hprof
那個result文件,我沒有查到是什么文件,先不管它啦,我們只要雙擊hprof文件即可。
稍等一會以后會出現一個分析框:
hprof
猛地一看好麻煩啊,不要慌,慢慢來,看多了漸漸就懂了。
這些字段的含義分別是:
名稱 描述
Class name 類名
Total Count 該類的實例總數
Heap Count 所選擇的堆中該類的實例的數量
Sizeof 單個實例所占空間大小(如果每個實例所占空間大小不一樣則顯示0)
Shallow Size 堆里所有實例大小總和(Heap Count * Sizeof)
Retained Size 該類所有實例所支配的內存大小
Instance 具體的實例
Reference Tree 所選實例的引用,以及指向該引用的引用。
Depth GC根節點到所選實例的最短路徑的深度
Shallow Size 所選實例的大小
Dominating Size 所選實例所支配的內存大小
然后我們看android studio右邊有一個Analyzer Tasks按鈕,我們點擊打開Analyzer Tasks面板,然后點擊運行,就可以在Analysis Results面板看到分析結果啦!
Analyzer Tasks
分析結果顯示我們的SecondActivity有內存泄漏
Leaked Activities
Leaked Activities : 有內存泄漏的activities
Duplicated Strings : 重復定義的字符串(一般可以不理會)
以上就是LeakCanary的使用方式啦 (* ̄︶ ̄)
今天是七夕,我相信只要努力,就可以收獲美好的愛情。越優秀的人會遇到越優秀的另一半。
---------------------
作者:月色下的獨輪車
來源:CSDN
原文:https://blog.csdn.net/baidu_31093133/article/details/81779711
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!