Android内存分析工具集【3】Android Studio 中的Android Profiler分析项目查找内存泄漏

前言:
在开发项目的过程中 或多或少都有些地方不注意造成内存泄漏导致App卡顿的情况发生 Android Studio也为我们提供了一些查找内存泄漏的组件 今天就先学习下 如何使用Android Monitor来分析和查找项目中内存泄漏的地方

案例:

public class CommUtil {
    private static CommUtil instance;
    private Context context;
    private CommUtil(Context context) {
        this.context=context;
    }
    public static CommUtil getInstance(Context context){
        if(null==instance){
            instance=new CommUtil(context);
        }
        return instance;
    }
}

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CommUtil instance = CommUtil.getInstance(this);
    }
}

将Activity的实例被一个单例对象所持有,相信这样的代码错误大家应该不会去犯,这里主要学习如何使用Android Monitor 就迁就一下,然后我们运行起来 ,再将手机屏幕旋转几下(旋转屏幕的时候 Activity会被销毁重新创建,但是这里的单例会持有销毁Activity的实例就造成内存泄漏)。

先看看Android Studio 的Android Monitor都有哪些功能 先只关注Memory这块

Android Studio 3.0 采用全新的Android Profiler窗口取代 Android Monitor 工具。 这些全新的分析工具能够提供关于应用 CPU、内存和网络 Activity 的实时数据。 您可以执行基于样本的函数跟踪来记录代码执行时间、采集堆转储数据、查看内存分配,以及查看网络传输文件的详情。

如下图,在android studio 3.1版本之后该工具不再提供Android Monitor工具集,而是提供Android Profile工具来分析CPU,内存,网络,ENERGY能耗分析四个模块的分析工具,

而 Memory Profiler 相当于将 MAT 的简化版功能集成到 AS 中。

1如点击AS下方的【1】Profiler卡片项显示此Android Profile界面,如你的AS未显示Profiler,可通过:AS工具栏View--Tool Windows --Profiler

 

如上图,

【1】点击左侧的对应的进程名即会在右侧出现该进程的四项功能分析,

【2】如双击右侧某项分析区域即可进入此功能的专项分析界面内,如下图,如要切换某分析项目,则点击下图的的【向下】箭头选择需要分析的某项功能

下文截图来自之前转载,可能界面截图与我上部分的界面不同,是因为各自的AS版本不同

Initiate Gc:点击主动去回收垃圾内存
Dump java Heap: 点击就会生成app运行内存快照.hprof文件
Free :代表还剩下的内存
Allocated:代表已经使用的内存

通过点击Android Studio右下角的Memory Monitor标签,打开工具可以看见较浅蓝色代表free的内存,而深色的部分代表使用的内存从内存变换的走势图变换,可以判断关于内存的使用状态,例如当内存持续增高时,可能发生内存泄漏;当内存突然减少时,可能发生GC等,如下图所示。

  1. Dump java Heap点击就会生成app运行内存快照.hprof文件

  2. 通过内存快照 看到MainActivity 在内存中有3个实例 点击进行进一步查看


    Depth:对象被引用的深度
    Shallow Size:对象实例的大小
    Dominating Size:对象管辖范围的内存大小

  3. 在Instance区域我们看到了MainActivity的3个实例对象 已经各个对象的引用深度和大小等 这里就明显看到了MainActivtiy内存泄漏了 这里说明一下 (在运行项目的时候 手机屏幕旋转了3下 所以生成了3个MianActivity实例 但是第二个MainActivity已经被回收 因为当GC回收的时候会将除了第0个和最后这一个留着其他的都会被回收 所以当你把手机屏幕旋转3次以上的时候 内存里面只会有2个Activity实例)
    点击编号2的MianActivity进行查看:


    Depth:对象被引用的深度
    Shallow Size:对象实例的大小
    Dominating Size:对象管辖范围的内存大小

  4. 根据上面的内存对象引用树就能得出结论分析(除CommUtil以外的地方是系统级的引用这里暂时先不用管) :

    • CommUtil引用了MainActivity的context
    • 引用深度Depth为1 对象大小为12 该对象管辖范围大小为60781
      然后改代码:

public class MainActivity extends AppCompatActivity {

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

        CommUtil instance = CommUtil.getInstance(getApplicationContext());
    }
}
  1. 该代码运行 且旋转屏幕后 再生成内存快照.hprof文件查看:

     

    将this改为getApplicationContext()后 MainActivity在几次旋转屏幕后始终保持一个实例

总结:

  • 以上是通过已知案例来进行对Android Monitor的简单学习 在实际开发过程中还需要去仔细的分析(这个相对来讲较困难 需要根据自己的一些经验来看)

最后:
作者:明朗__
链接:https://www.jianshu.com/p/db71488349a0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值