美文网首页
Android性能优化—内存泄漏分析之DDMS和MAT(二)

Android性能优化—内存泄漏分析之DDMS和MAT(二)

作者: aositeluoke | 来源:发表于2020-02-29 22:32 被阅读0次

      之前,我们一直都在使用Android Device Monitor对我们的应用进行各种分析,也建立了很深厚的感情,而如今,Android Device Monitor 已在 Android Studio 3.1 中弃用,并已从 Android Studio 3.2 中移除,也意味着它即将要退役,离我们越来越远了,为了纪念这位曾经对App做出巨大贡献的应用,让我们回顾一下它的事迹!

    准备工作

    Android Device Monitor

    打开后它的主页面如图一,如果有些窗格没有展示出来,可以点击window-Reset Perspective-Yes重置下配置,或者点击window-Show View选择自己想要展示的窗格


    图一.png
    Devices

      设备列表如图二所示,选择某应用后,红色框内的图标就会点亮,供您使用,他们的具体信息从左到右介绍如下:

    • Debug Process:调试进程,该按钮一直处于灰色状态不能点击
    • Update Heap:更新堆信息,点击后它,结果将会在Heap窗格中展示
    • Dump HPROF file:获取hprof文件(常用),官方推荐使用新工具CPU Profiler
    • Cause GC:垃圾回收
    • Update Threads:更新线程信息,结果在Threads中展示
    • Start Method Profiling:启动方法分析,官方推荐使用新工具CPU Profiler
    • Stop Process:停止进程
    • Screen Capture:屏幕截图
    • Dump View Hierarchy for UI Automator:视图层级转储(常用),官方推荐使用新工具Layout Inspector,用Layout Inspector查看视图层级时,如果您的设备没有安装Google Play商店且已获得root权限才能看到正在运行的应用,否则,只能看到正在运行的可调试应用。如果您想在非root手机上查看正在运行的不可调试应用视图,建议您使用Dump View Hierarchy for UI Automator尝试一下
    • Capture System Wide Trace:捕获系统信息
    • Reset adb:重置安卓调试桥
    • Start OpenGL Trace:开启OpenGL跟踪


      图二.png

    Dump HPROF file

      此功能主要用来生成.hprof文件,对于该文件的分析,还需要工具Eclipse Memory Analyzer打开才行。monitor生成的.hprof文件并不是标准的、MAT可识别的文件,因此,需要我们把.hprof转成标准的文件后,才能使用MAT工具进行分析,转换步骤如下:

    • 打开命令行工具
    • 输入hprof-conv -z A.hprof B.hprof,如果提示命令hprof-conv用不了的话,请切换到android sdk/platform-tools后再操作
    • A.hprof为转换前的文件
    • B.hprof为转换后的文件
        在这里,我们创建一个项目,故意让一个单例类SingleInstance持有SingleInstanceActivity对象导致内存泄漏,接着使用DDMS工具生成.hprof文件,然后再使用上面的命令换成标准的.hprof文件后,我们就可以进入MAT的世界了!
      该测试项目只有三个Java文件如下
      MainActivity.java
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = MainActivity.class.getName();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        public void onSingleInstance(View view) {
            Intent intent = new Intent(this, SingleInstanceActivity.class);
            startActivity(intent);
        }
    }
    

    SingleInstance.java

    public class SingleInstance {
        private static Context context;
        private static SingleInstance singleInstance;
        private SingleInstance() {
       }
        public static SingleInstance getInstance(Context ctx) {
            if (singleInstance == null) {
                context = ctx;
                singleInstance = new SingleInstance();
            }
            return singleInstance;
        }
    }
    

    SingleInstanceActivity.java

    public class SingleInstanceActivity extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_single_instance);
            SingleInstance.getInstance(this);
        }
    }
    

      运行App后,先点击Dump HPROF file一次获取没有产生内存泄漏的unml.hprof文件,接着依序打开SingleInstanceActivity-点击返回键,在DDMS中频繁点击GC,再继续获取有内存溢出的ml.hprof文件,然后将unml.hprof转换成unml_stantard.hprof文件,将ml.hprof转换成ml_stantard.hprof文件。

    MAT

      使用MAT打开我们刚才生成的unml_stantard.hprof文件,打开步骤:File->Open Heap Demp,打开后默认展示如图三所示,这个时候我们点击Histogram如图四所示,然后在红框这个地方输入我们的包名敲回车如图五所示,红框这个地方显示,只存在一个实例,也就是MainActivity,同样的操作,我们在ml_stantard.hprof看一下,ml_stantard的Histogram如图六所示,这个时候我们发现SingleInstanceActivity还存在呢,内存泄漏也就产生了,无论我们GC多少次,由于该对象被单例对象持有,而单例对象生命周期和应用一致,所以导致SingleInstanceActivity不能回收。


    图三.png
    图四.png
    图五.png
    图六.png

    最后,我们简单总结一下整个操作流程如下:

    • 启动应用
    • 打开monitor,选择应用
    • 点击Dump HPROF file生成.hprof文件
    • 打开怀疑内存泄漏的页面后,关闭,频繁GC操作
    • 再次生成.hprof文件
    • 将两个.hprof文件转换成标准的文件
    • 使用MAT工具打开.hprof文件
        其实,整个操作流程还是挺麻烦的,读者朋友们了解一下就可以了,因为Google还提供了另一种更加便利的方式,想了解的朋友可以看一下上一篇文章Android性能优化—内存泄漏分析(一)

    相关文章

      网友评论

          本文标题:Android性能优化—内存泄漏分析之DDMS和MAT(二)

          本文链接:https://www.haomeiwen.com/subject/ldyphhtx.html