性能優化總結2:leakcanary的使用(簡潔易懂)


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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM