Android 性能优化工具

来源:互联网 发布:淘宝特价群怎么做 编辑:程序博客网 时间:2024/05/22 15:52

1. Allocation Tracker

Allocation Tracker是android studio自带的一个功能,我们可以在MemoryMonitor中打开使用:
这里写图片描述
如上图,点击红框按钮,start allocation tracking 然后操作app,开始allocation tracking,当认为需要结束的时候,再次点击按钮,稍等片刻,即可以在android studio中dump出在 这段时间内新申请对象的信息
Size就是内存大小,Count就是分配了多少次内存
详细解释见这位大神的博客:
http://blog.csdn.net/itfootball/article/details/48750849

2. 内存监测工具 DDMS —> Heap+ MAT 解决内存泄漏

Dump Java Heap

这里写图片描述
如上图Android monitors——memory——第三个按钮,打印当前堆栈的对象,Analyzer Task 可以检测内存泄露的activity,并指出泄露的代码位置。
这里写图片描述

名称 意义 Total Count 内存中该类的对象个数 Heap Count 堆内存中该类的对象个数 Sizeof 物理大小 Shallow size 该对象本身占有内存大小,不包含其引用的对象 Retained Size/Dominating size 是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,释放该对象后,节省的内存大小

“Update Heap”——“Cause GC”

这里写图片描述
此时在Heap视图中就会看到当前选中的进程的内存使用量的详细情况,说明:
a) 点击“Cause GC”按钮相当于向虚拟机请求了一次gc操作;
b) 当内存使用信息第一次显示以后,无须再不断的点击“Cause GC”,Heap视图界面会定时刷新,在对应用的不断的操作过程中就可以看到内存使用的变化;
这里写图片描述

“dump hprof file”

这里写图片描述

生成hprof文件,需要用命令 sdk/tools/hprof-conv src.hprof des.hprof 转换一下,才能用mat打开。或者使用工具转换格式,如下图:
这里写图片描述

其中Histogram可以看到所有实例的分配情况, Dominator Tree列出了堆的最大对象。 Leak Suspects主要是列出怀疑的内存泄露处(感觉没什么用,找到的地方都不是泄漏点,应该是我打开方式不对)。
这里写图片描述

Histogram界面

Merge Shortest Paths to GC Roots 可以查看一个对象到RC Roots是否存在引用链相连接, 在JAVA中是通过可达性(Reachability Analysis)来判断对象是否存活,这个算法的基本思想是通过一系列的称谓”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走得路径称为引用链,当一个对象到GC Roots没有任何引用链相连则该对象被判定为可以被回收的对象,反之不能被回收,我们可以选择 exclude all phantom/weak/soft etc.references(排查虚引用/弱引用/软引用等)因为被虚引用/弱引用/软引用的对象可以直接被GC给回收.
group by package 然后找到应用的包,就能看到当前的内存情况。(把APP退出之后,如果还能看到应用的内存消耗,基本都是内存泄漏点)

这里写图片描述

这里写图片描述
List object - With outgoing References 显示选中对象持有那些对象
List object - With incoming References 显示选中对象被那些外部对象所持有
Show object by class - With outgoing References 显示选中对象持有哪些对象, 这些对象按类合并在一起排序
Show object by class - With incoming References 显示选中对象被哪些外部对象持有, 这些对象按类合并在一起排序

OQL(类似sql查询的功能)

select * from instanceof android.app.Activity

activity泄漏的解决方法
使用弱引用 + 静态内部类 解决activity泄漏的问题
这里写图片描述

DDMS —— update threads

这里写图片描述
利用DDMS 来分析主线程和其他工作线程是否出现阻塞,并找出 阻塞的原因。

在应用程序中进行让UI 出现卡顿的操作,在右边的视图中查看 main 线程,如果线程的状态显示 monitor,这表示 main 线程因为 请求同步锁而处于阻塞状态。点击Refresh 按钮查看线程是因为什么原因而阻塞。
   DDMS 中Threads 的状态的说明
   running – executing application code – 正在执行应用程序,准确的来说正在处理消息。
   sleeping – called Thread.sleep() – 执行了Thread.sleep() 方法,线程让出了CPU,正在休眠。
   monitor – waiting to acquire a monitor lock – 在正等待获取一个监听锁,线程被阻塞。
   wait – in Object.wait() – 在Object.wait() 方法中,线程被阻塞。
   native – executing native code – 执行了原生代码,这个对于 带有消息队列的线程是正常的状态,表示消息队列没有任何消息,线程在native 代码中进行无限循环,直到消息队列中出现新的消息,消息队列才会返回Java 代码处理消息。
   vmwait – waiting on a VM resource – 正在等待一个虚拟机资源
   zombie – thread is in the process of dying – 该线程已死
   init – thread is initializing (you shouldn’t see this) – 线程正在初始化 (你不会看到这个)
   starting – thread is about to start (you shouldn’t see this either) – 线程正在启动中 (这个你也不会看到)

utime
– cumulative time spent executing user code, in “jiffies” (usually 10ms). Only available under Linux.
– 执行用户代码的累计时间, 单位为”jiffies(表示系统启动以来的tick数)” (通常是 10ms). 仅在Linux系统中适用.
stime
– cumulative time spent executing system code, in “jiffies” (usually 10ms).
– 执行系统代码的累计时间, 单位为”jiffies(表示系统启动以来的tick数)”.
这里写图片描述

DDMS——Systrace

1.android device monitor 生产文件
这里写图片描述
2. 命令行生成文件
cdandroidsdk/platformtools/systrace python systrace.py –time=10 -o mynewtrace.html sched gfx view wm

参数名 意义 -h, –help 帮助信息 -o 保存的文件名 -t N,–time=N 多少秒内的数据,默认为5秒,以当前时间点往后倒N个时间 -b N,–buf-size=N 单位为千字节,限制数据大小 -k –ktrace= 追踪特殊的方法 -l,–list-categories 设置追踪的标签 -a ,–app= 包名 –from-file= 创建报告的来源trace文件 -e ,–serial= 设备号

其中标签可选项如下:

标签名 意义 gfx Graphics input Input view View webview Webview vm Window Manager am Activity Manager audio Audio video Video camera Camera hal Hardware Modules res Resource Loading dalvik Dalvik VM rs RenderScript sched Cpu Scheduling freq Cpu Frequency membus Memory Bus Utilization idle Cpu Idle disk Disk input and output load Cpu Load sync Synchronization Manager workq Kernel Workqueues

以上标签并不支持所有机型,还有要想在输出中看到任务的名称,需要加上sched.

生成trace的HTML文件之后用chrome打开,地址栏中输入chrome://tracing 然后load进trace文件
Alert 是可能有问题的地方,如下图所示
这里写图片描述

这里写图片描述
红色或黄色帧为是可能有性能问题的地方,这里能看到每个方法执行的顺序和时间。
这里写图片描述

点击哪一块,就可以看到个方法的信息。

Systrace也只能提供一个概览,给出性能问题的提示(Alert),他的深度是有限的。所以要找到我们app中到底是什么让我们的CPU繁忙,我们还要借助另一个工具——Traceview。

public void ProcessPeople(){
Trace.beginSection(“ProcessPeople”);
try{
Trace.beginSection(“Processing Jane”);
try{
// code for Jane task…
}finally{
Trace.endSection();// ends “Processing Jane”
}

    Trace.beginSection("Processing John");    try{        // code for John task...    }finally{        Trace.endSection();// ends "Processing John"    }}finally{    Trace.endSection();// ends "ProcessPeople"}

}

DDMS —— TraceView查看每个方法所消耗的cpu时间

// start tracing to “/sdcard/calc.trace”
Debug.startMethodTracing(“calc”);
// …
// stop tracing
Debug.stopMethodTracing();

adb pull /sdcard/calc.trace /tmp
这里写图片描述

http://blog.csdn.net/itfootball/article/details/48792435

Hotspot的查找是一个细致的工作,需要开发者对目标程序的代码,以及Traceview工具都比较熟悉才行。

名称 意义 Name 方法的详细信息,包括包名和参数信息 Incl Cpu Time Cpu执行该方法该方法及其子方法所花费的时间 Incl Cpu Time % Cpu执行该方法该方法及其子方法所花费占Cpu总执行时间的百分比 Excl Cpu Time Cpu执行该方法所话费的时间 Excl Cpu Time % Cpu执行该方法所话费的时间占Cpu总时间的百分比 Incl Real Time 该方法及其子方法执行所花费的实际时间,从执行该方法到结束一共花费的时间(可能包含io或者其他阻塞的时间?) Incl Real Time % 上述时间占总的运行时间的百分比 Excl Real Time % 该方法自身的实际允许时间 Excl Real Time 上述时间占总的允许时间的百分比 Calls+Recur 调用次数+递归次数,只在方法中显示,在子展开后的父类和子类方法这一栏被下面的数据代替 Calls/Total 调用次数和总次数的占比 Cpu Time/Call Cpu执行时间和调用次数的百分比,代表该函数消耗cpu的平均时间 Real Time/Call 实际时间于调用次数的百分比,该表该函数平均执行时间

这里写图片描述

DDMS——HierarchyViewer 开启

Configuring Devices

Enable Developer Options on your mobile device.
Depending on the type of device you have, do one of the following:
If you have a locked device running Android 4.0 or lower, follow the instructions for installing and configuring ViewServer.
If you have an unlocked device running Android 4.0 or lower, no further configuration is needed.
If you have a device running Android 4.1 or higher, you must set an environment variable on your development machine. For more information, see Setting the ANDROID_HVPROTO variable
Setting the ANDROID_HVPROTO variable

Windows

Click My Computer > Property > Advanced > Environment Variables.
Click New.
In variables name put: ANDROID_HVPROTO
In variable value put: ddm
Click OK<./li>

publicclassMyActivityextendsActivity {publicvoidonCreate(BundlesavedInstanceState) {    super.onCreate(savedInstanceState);    // Set content view,etc.    ViewServer.get(this).addWindow(this);}publicvoidonDestroy() {    super.onDestroy();    ViewServer.get(this).removeWindow(this);}publicvoidonResume() {    super.onResume();    ViewServer.get(this).setFocusedWindow(this);}}

这里写图片描述
点击Profile Node,你会发现所有的子View上面都有了3个圈圈,
(取色范围为红、黄、绿色),这三个圈圈分别代表measure 、layout、draw的速度,并且你也可以看到实际的运行的速度,如果你发现某个View上的圈是红色,那么说明这个View相对其他的View,该操作运行最慢,注意只是相对别的View,并不是说就一定很慢。
红色的指示能给你一个判断的依据,具体慢不慢还是需要你自己去判断的。

0 0