(2018.11.08)Android Profiler基础使用


(转载公司内部论坛本人文章2018.11.08)

一、概览

导语 : 2017年Google I/O大会上发布了Android Studio 3.0,其中一项更新是将之前内置的Android Monitor换成了Android Profiler。最新版Android Studio3.2已经移除了DDMS的入口了,感觉Google是想用Android Profiler完全取代DDMS。

Google官网有几篇文章介绍了Android Profiler使用方法,这里我只是做了一下搬运工,结合自己的Demo得出的一些理解。如果有理解错漏的地方,欢迎指出。

个人觉得Android Profiler相比DDMS最大的优势在于它集成于Android Studio,为我们Android应用提供了 实时 检测工具,同时界面交互比较友好,能够快速简单的获取到我们想要的CPU,内存等信息。

Profiler入口:点击 ** View > Tool Windows > Android Profiler** ,或者点击Studio右下角的Profiler。
在这里插入图片描述
打开之后界面如下图,CPU,MEMORY(内存),NETWORK(网络),ENERGY(耗电,android studio3.2新增)四大部分。本文主要介绍 CPU内存 部分。
在这里插入图片描述

二、CPU Profiler(CPU分析器)

CPU Profiler 可帮助我们实时检查应用的 CPU 使用率和线程活动,并进行函数跟踪,以便我们优化和调试应用代码。打开视图如下:
在这里插入图片描述

  1. Event 时间线: 显示应用中Activity的生命周期,及用户与设备交互事件,比如按返回键,屏幕旋转等。

  2. CPU 时间线: 分别显示了应用的实时 CPU 使用率,其他进程的CPU使用率,以及应用使用的线程数。

  3. 线程活动时间线: 列出进程的每个线程,并使用下面列出的颜色沿时间线标示它们的活动情况。

  • 绿色: 表示线程处于活动状态或准备使用 CPU。 即,它正在“运行中”或处于“可运行”状态。

  • 黄色: 表示线程处于活动状态,但它正在等待一个 I/O 操作(如磁盘或网络 I/O),然后才能完成它的工作。

  • 灰色: 表示线程正在休眠且没有消耗任何 CPU 时间。 当线程需要访问尚不可用的资源时偶尔会发生这种情况。 线程进入自主休眠或内核将此线程置于休眠状态,直到所需的资源可用。

下面我用一个简单的Demo说明CPU Profiler的使用,先看测试代码:

public class ProfilerActivity extends AppCompatActivity {
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendEmptyMessageDelayed(1, 500);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profiler);
        mHandler.sendEmptyMessage(1);
    }
}

代码比较简单,在Activity中有一个Handler,500ms循环一次,每次让线程sleep100ms,记录CPU使用情况,点击上面的 Record 按钮,大约3秒后Stop,会生成如下四个视图(Call Chart、Flame Chart、Top Down、Bottom Up)
在这里插入图片描述

1、Call Chart(调用图)

Call Chart图如上图。其实在真实项目中,生成的图比这个看起来复杂多了。但只要你弄清它们的关系,Call Chart展示的调用关系还是挺清晰的。

首先每个横条代表一个函数的运行时间,具体颜色区分如下:

  • 橙色: 对系统 API 的函数调用

  • 绿色 :对应用自有函数的调用

  • ** 蓝色:** 对第三方 API(包括 Java 语言 API)的函数调用

Call Chart图可以简化为下面表示例:
在这里插入图片描述

图中看出,D函数的运行时间 Total time = Self Time + Children time (C和B的运行时间)

鼠标放在每个横条上会显示函数的运行时间,如图显示每次 handleMessage()方法大约执行了102ms,然后大概500ms循环一次。 点击右键还可以Jump to Source跳转到原代码处。

总结:Call Chart图显示了应用内所有函数的调用关系以及运行时间,方便开发者快速查看某个时间点应用内函数的调用和耗时情况。

2、Flame Chart(火焰图)

在这里插入图片描述

切换至Flame Chart。Flame Chart颜色没有特殊含义。看似是Call Chart的倒置,其实不完全是这样。Flame Chart会将调用顺序完全相同的函数归类成一个横条,怎么理解这个调用顺序相同呢?如下的调用图(Call Chart)
在这里插入图片描述

由于 B^1、B2^ 和 B^3^ 共享相同的调用顺序 (A → D → B),所以在火焰图(Flame Chart)中会合并成一个横条。同理,C^1^ 和 C^3^ 也会汇总在一起。所以Flame Chart图如下:
在这里插入图片描述

此时,X轴不在表示调用时间,而表示每个函数相对的运行总时间。

总结:Flame Chart更方便开发者查询哪些函数消耗的时间最多。火焰图如果看顶层的哪个函数占据的宽度比较大,就表示该函数可能存在性能问题。

3、Top Down

Top Down显示一个函数调用列表,展开后可以查看函数的被调用方。可以理解为,Flame chart 是Top down 的图形化表示形式。
在这里插入图片描述

4、Bottom Up

Bottom Up列出了所有执行函数的时间,点开后是它的调用方,按运行时间排序。
在这里插入图片描述

三、Memory Profiler(内存分析器)

Memory Profiler显示一个应用内存使用量的 实时图表 ,可以 捕获堆转储 、以及 跟踪内存分配
在这里插入图片描述

  1. 分别是强制垃圾回收按钮,Dump Java Heap(捕获堆转储)按钮,如果是Android7.1及以下系统,旁边会Record按钮。

  2. 实时显示了每个内存类别使用了多少内存,虚线表示分配的对象数,以及垃圾回收Event图标。
    在这里插入图片描述
    内存计数的类别如下:

  • Total: 应用占用内存总量

  • Java: 从 Java 或 Kotlin 代码分配的对象内存。

  • Native: 从 C 或 C++ 代码分配的对象内存。即使您的应用中不使用 C++,您也可能会看到此处使用的一些原生内存,因为 Android 框架使用原生内存代表您处理各种任务,如处理图像资源和其他图形时,即使您编写的代码采用 Java 或 Kotlin 语言。

  • Graphics: 图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。 (请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)

  • Stack: 您的应用中的原生堆栈和 Java 堆栈使用的内存。 这通常与您的应用运行多少线程有关。

  • Code: 您的应用用于处理代码和资源(如 dex 字节码、已优化或已编译的 dex 码、.so 库和字体)的内存。

  • Other: 您的应用使用的系统不确定如何分类的内存。

  • Allocated: 您的应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。

1.Dump Java Heap(捕获堆转储)

点击上面的Dump Java Heap  按钮,过会会倒出你应用java堆中所有的类型
在这里插入图片描述

图中可以看到应用中自己的Activity,右边数字栏所表示的意义如下:

  • Allocations: 该类在堆中已分配实例数

  • Native Size: 由 C 或 C++ 代码分配的实例总大小

  • Shallow Size :此堆中所有实例的总大小(以字节为单位)。

  • Retained Size 为此类的所有实例而保留的内存总大小(以字节为单位)。

图中可以看到ProfilerActivity实例数是3,为什么会是3呢?可以看到demo代码中,我用非静态Handler实现了一个定时逻辑,非静态内部类默认持有外部类引用,所以造成了内存泄漏。ProfilerActivity启动了3次,所以就会有三个。点击右边会显示Instance View图。这就是堆中那三个ProfilerActiity,展开还可以看到实例内部的组成。
在这里插入图片描述在这里插入图片描述

点击单个实例,下方会显示该实例的References(引用图),显示该实例的所有引用。可以看到第一个引用就是那个Handler,点击右键Jump To Source果然跳转到Hander初始化代码处。
在这里插入图片描述

由于我这个是demo代码,页面代码比较简单,所以很容易就能找出自己代码中出现的泄漏问题。但是实际项目中查找起来会复杂很多。这里有一个小技巧,在Heap图中可以通过切换按包名排序(Arrange by package),通过包名,我们能更方便的查找到我们所关心的类的内存占用情况。
在这里插入图片描述
在这里插入图片描述

2、跟踪内存分配

如果你的设备是Android 8.0及以上的,可以随时在内存图上拖动鼠标,选取你想要查看内存分配的时间段。如果你的设备是 Android 7.1 或更低版本,则在 Memory Profiler 工具栏中点击 Record按钮 。 记录时,Android Monitor 将跟踪您的应用中进行的所有分配。
在这里插入图片描述

选取时间段后会生成Live Allocation图,右边数字栏所表示的意义如下(在你所选取的时间段内):

  • Allocations: 表示你所选取时间段内,该类在堆中已分配实例数

  • Deallocations: 表示你所选取时间段内,该对象在内存中被回收的次数。

  • Total Count 总数。

  • Shallow Size 所有实例的总大小(以字节为单位)

点击查看Instance View图,可以看到 User对象ItemsActivity 的创建时间和回收时间基本是一致的。并且在Allocation Call Stack中还可以看到User对象是在ItemsActivity的o nCreate() 方法里被创建的。
在这里插入图片描述
在这里插入图片描述

public class ItemsActivity extends AppCompatActivity {
    private User mUser;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profiler);
        mUser = new User();
    }
}

总结:Memory Profiler可以让我们很方便的查看我们应用的内存占用情况,并且可以很方便实现对单对象的内存追踪和检测内存泄漏等

以上是我对Android Profiler使用方法的一些介绍,其中的错漏,欢迎指出,大家一起探讨。

参考资料:

https://developer.android.google.cn/studio/profile/

END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity-debugging-2018.x.zip是一个Unity版本相关的调试工具包,其中包含了诸如埋点工具和调试插件等功能丰富的工具。这些工具可以帮助Unity开发者在开发自己的游戏时快速、准确地定位和修复代码中的问题,提高了游戏的开发效率和质量。 这个工具包中最值得注意的一点是它的兼容性。它可以与Unity 2018中的许多不同版本一起使用,这意味着无论开发者使用哪个具体版本的Unity,都可以使用这个工具包进行调试。这为开发过程中遇到的问题提供了更为广泛和全面的支持,从而更好地满足了不同开发者的需求和要求。 另外,这个工具包还有一个很不错的特色,就是它的易用性。它提供了直观和易于操作的界面,即使是那些对调试工具很不熟悉的开发者也可以使用它。开发者可以通过它直接在Unity编辑器中观察代码执行过程中的变化,非常方便。 总的来说,Unity-debugging-2018.x.zip是一个非常实用和友好的Unity调试工具包,可以帮助Unity开发者更快速、高效地开发自己的游戏。 ### 回答2: unity-debugging-2018.x.zip是Unity引擎中用于调试的工具包。在程序开发的过程中,会出现各种各样的问题,而调试是解决这些问题的重要手段之一。Unity-debugging-2018.x.zip提供了一系列工具和功能,帮助程序员定位和解决问题。 Unity-debugging-2018.x.zip中包含了各种调试工具,例如调试器、内存分析器、性能分析器等等。这些工具可以帮助开发者监控程序运行的状态,包括内存使用、CPU使用、函数运行时间等等。通过这些信息,开发者可以找到程序中可能存在的性能问题,并对其进行优化。 同时,Unity-debugging-2018.x.zip还提供了调试器,帮助开发者调试程序。开发者可以在调试器中设置断点,一步一步地执行程序,查看变量和函数调用的情况。通过调试器,开发者可以快速定位程序中的错误,减少排错的时间。 总之,Unity-debugging-2018.x.zip是Unity开发中不可或缺的工具包。它可以帮助开发者定位和解决问题,提高程序的稳定性和性能,为游戏开发提供强有力的支持。 ### 回答3: unity-debugging-2018.x.zip是一个用于Unity引擎调试的文件。Unity是一款流行的游戏开发引擎,但在游戏开发过程中难免会遇到各种问题,例如程序崩溃、游戏运行异常等等。此时就需要进行调试。Unity-debugging-2018.x.zip文件中包含了一系列调试工具,可用于分析和诊断Unity游戏/应用程序的问题。其中包括了Unity自带的Profiler(性能分析器)、Debug.Log、断点调试、MonoDevelop等工具,这些工具可以帮助开发者查找问题所在,快速调试程序。一个好的调试工具不仅能帮助开发者快速找到问题,还能提高开发效率,使开发工作更加顺利。总之,Unity-debugging-2018.x.zip文件是Unity调试工具的集合,为开发者解决问题提供了极大的帮助,也是一个值得推广和使用的工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值