使用Android Studio 查看内存泄漏

用新版的AS 的profiler 查看内存泄漏

记录一下使用Android Studio 的profiler 查看内存泄漏的过程。新版的AS 的profiler 功`能强大。我们可以很方便的查看到一个界面里的内存泄漏。

首先我们制造一个内存泄漏的Activity

public class MemoryLeakActivity extends AppCompatActivity {
    
    

    private static int FLAG = 999;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_memory_leak);

        Button btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                finish();
            }
        });

        mHandle.sendEmptyMessageDelayed(FLAG, 1000);

    }


    private Handler mHandle = new Handler(Looper.myLooper()) {
    
    
        @Override
        public void handleMessage(@NonNull Message msg) {
    
    
            super.handleMessage(msg);
            mHandle.sendEmptyMessageDelayed(FLAG, 1000);
        }
    };

 
}

然后点开AS 的profiler
在这里插入图片描述
然后我们可以查看到我们应用运行时候的cpu 内存等数据的情况。这里我们只要关注内存即可。
在这里插入图片描述

接下来我们从启动页面跳转到有内存泄漏的那个Activity。

在这里插入图片描述
这里可以看到我们从LunchActivity 跳转到了MemoryLeakActivity。

接下来我们点击button finish()掉 MemoryLeakActivity。回到我们原来的起动页面。这时候点垃圾桶,触发几次gc。

在这里插入图片描述

这些小垃圾桶就代表我们触发的gc.

在这里插入图片描述

然后选取record 来记录我们产生的内存泄漏。

在这里插入图片描述
新版的AS的Record 点一下就可以为我们自动记录一段内存快照。然后直接弹出我们的内存数据。不用像以前一样你需要拉一段距离。

这里很清晰的给我们指出有2出内存泄漏。

在这里插入图片描述

点一下这个 2 Leaks 就会直接显示出内存泄漏的类的包名位置(非常人性化)。

在这里插入图片描述
这里我们看到内存泄漏的位置一个是我们自己的Activity里Handler 造成的内侧泄漏。一处是系统里ReportFragment发生的内侧泄漏。 这个估计也跟Handler 有关。

然后我们点到相关的类还可以进一步查看内存泄漏的类的引用关系

在这里插入图片描述

使用MemoryAnalyzer

我们也可以导出内存快照。使用mat来进行内存分析。

在这里插入图片描述

首先使用 hprof-conv.exe 来转换一下我们导出的内存快照。记得把platform-tools 配置到环境变量里你才能找到hprof-conv 这个命令。

在这里插入图片描述

 hprof-conv -z 1.hprof 1-mat.hprof

生成一个新文件

在这里插入图片描述

打开Mat 导入 1-mat.hprof : file->Open Dump Heap 。 点击finish

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这里 Shallow Size是对象本身占据的内存的大小,不包含其引用的对象。对于常规对象(非数组)的Shallow Size由其成员变量的数量和类型来定,而数组的ShallowSize由数组类型和数组长度来决定,它为数组元素大小的总和。

Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C,C就是间接引用) ,并且排除被GC Roots直接或者间接引用的对象。

我们进一步操作排除软引用,弱引用,虚引用看看剩下哪些东西。

在这里插入图片描述
然后我们就可以看到排除完软引用,弱引用,虚引用后内存里剩下的对象。根据剩余的对象来分析内存泄漏。

整体来看Mat 不如新版AS的profiler好用。新版AS的profiler基本上算是傻瓜式的使用了。只要目前看在安卓开发中只要会用新版AS 的profiler 即可。

Guess you like

Origin blog.csdn.net/qq_33667332/article/details/122483348