栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android性能全面分析与优化方案研究—几乎是史上最全最实用的

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android性能全面分析与优化方案研究—几乎是史上最全最实用的

如何开启该功能:AndroidStudio中,Tools — Android — Android Devices Monitor

该工具的缺点:使用起来麻烦。

  • 看看项目中遇到的问题(MainTabAvtivity)。

1、merge标签的使用

未使用merge,例如:XLTabLayout.java

使用merge,例如:账号信息页的条目UserAccountItem

2、include标签的使用导致的问题

3、避免创建不必要的层级(MainTabActivity)

4、ViewStub的使用

这个标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。

通常情况下我们需要在某个条件下使用某个布局的时候会通过gone或者invisible来隐藏,其实这样的方式虽然隐藏了布局,但是当显示该界面的时候还是将该布局实例化的。使用ViewStub可以避免内存的浪费,加快渲染速度。

其实ViewStub就是一个宽高都为0的一个View,它默认是不可见的,只有通过调用setVisibility函数或者Inflate函数才会将其要装载的目标布局给加载出来,从而达到延迟加载的效果,这个要被加载的布局通过android:layout属性来设置。

当准备inflate ViewStub时,调用inflate()方法即可。还可以设定ViewStub的Visibility为VISIBLE或INVISIBLE,也会触发inflate。注意的是,使用inflate()方法能返回布局文件的根View。

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);

// or

View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

setVisibility的时候会触发了inflate

注意:使用ViewStub加载的布局中不能使用merge标签。

  • 看看Space标签(不常用)

space标签可以只在布局文件中占位,不绘制,Space标签有对应的java类Space.java,

通过阅读源码可以发现,它继承至View.java,并且复写了draw方法,

该方法为空,既没有调用父类的draw方法,也没有执行自己的代码,表示该类是没有绘制操作的,

但onMeasure方法正常调用,说明是有宽高的。

主要功能用来设置间距,这个标签不常用,常使用margin或padding。

[](()3、介绍一下查看渲染性能的工具


  • GPU呈现模式分析(大致定位问题)

开发者选项 — GPU呈现模式分析 — 选择“在屏幕上显示为条形图”

Android开发者选项——Gpu呈现模式分析,参考:http://www.voidcn.com/blog/gjy211/article/p-6210447.html

自动播放的视频停止的时候会有两条很长的柱线,下个视频播放的时候还会有一条。这里有一个明显的卡顿。

播放器操作(DefaultPlayerView.java - doPlay,player_auto_control_layout.xml):

上图的E total time = 68 是播放器停止播放的时候耗费的时间。

total time = 29 是播放器开始播放的时候耗费的时间。

其中,大部分时间耗费在了 5total time = 18 上面,这个是inflate播放器界面的时候耗费的时间。

是不是所有的inflate都很耗费时间,看一下账号信息页:

  • GPU Monitor

  • 启用严格模式(不止渲染性能)

应用在主线程上执行长时间操作时会闪烁屏幕。

通过代码进行严格模式(StrictMode)调试,参考:http://www.tuicool.com/articles/ueeM7b6

[](()二、内存问题


[](()1、内存浪费


程序内存的管理是否合理高效对应用的性能有着很大的影响。

推荐阅读Android性能优化典范-第3季,参考:http://hukai.me/android-performance-patterns-season-3/

  • ArrayMap(我们项目中没有用到,Android源码中很多使用)

Android为移动操作系统特意编写了一些更加高效的容器,例如ArrayMap、SparseArray。

为了解决HashMap更占内存的弊端,Android提供了内存效率更高的ArrayMap。

1、先来看看HashMap的原理

HashMap的整体结构如下:

存储位置的确定流程:

2、再看来看看ArrayMap是如何优化内存的

它内部使用两个数组进行工作,其中一个数组记录key hash过后的顺序列表,

另外一个数组按key的顺序记录Key-Value值,如下图所示:

当你想获取某个value的时候,ArrayMap会计算输入key转换过后的hash值,然后对hash数组使用二分查找法寻找到对应的index,

然后我们可以通过这个index在另外一个数组中直接访问到需要的键值对。

既然ArrayMap中的内存占用是连续不间断的,那么它是如何处理插入与删除操作的呢?它跟HashMap有什么区别?

二者之间的删除插入效率有什么差异?请看下图所示,演示了Array的特性:

HashMap与ArrayMap之间的内存占用效率对比图如下:

与HashMap相比,ArrayMap在循环遍历的时候更加高效。

什么时候使用ArrayMap呢?

1、对象个数的数量级最好是千以内,没有频繁的插入删除操作

2、数据组织形式包含Map结构

  • Autoboxing(避免自动装箱)

Autoboxing的行为还经常发生在类似HashMap这样的容器里面,对HashMap的增删改查操作都会发生了大量的autoboxing的行为。

当key是int类型的时候,HashMap和ArrayMap都有Autoboxing行为。

  • SparseArray(项目中用到较多 – 后面再说如何利用工具查找该用SparseArray而没有用到的地方)

为了避免Autoboxing行为Android提供了SparseArray,此容器使用于key为int类型。

SparseBooleanMap,SparseIntMap,SparseLongMap等容器,是key为int,value类型相应为boolean、int、long等。

  • Enum(枚举,项目中较多使用,应尽量避免)

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

Android官方强烈建议不要在Android程序里面使用到enum。

关于enum的效率,请看下面的讨论。假设我们有这样一份代码,编译之后的dex大小是2556 bytes,

在此基础之上,添加一些如下代码,这些代码使用普通static常量相关作为判断值:

增加上面那段代码之后,编译成dex的大小是2680 bytes,相比起之前的2556 bytes只增加124 bytes。假如换做使用enum,情况如下:

使用enum之后的dex大小是4188 bytes,相比起2556增加了1632 bytes,增长量是使用static int的13倍。

不仅仅如此,使用enum,运行时还会产生额外的内存占用,如下图所示:

推荐一些文章:

  • HashMap,ArrayMap,SparseArray源码分析及性能对比,参考:

http://www.jianshu.com/p/7b9a1b386265#

  • Android性能优化–小心自动装箱:http://blog.csdn.net/lgz_ei/article/details/69208784

  • Android性能优化篇:Android中如何避免创建不必要的对象:

http://blog.csdn.net/jia635/article/details/52525243

  • HashMap、ArrayMap、SparseArray分析比较:

http://blog.csdn.net/chen_lifeng/article/details/52057427

  • Android性能优化之String篇:http://www.androidchina.net/5940.html

  • SharedPreferences的commit和apply分析:

http://blog.csdn.net/u010198148/article/details/51706483

[](()2、内存泄漏


  • 什么是内存泄漏?

一些不用的对象被长期持有,导致内存无法被释放。

  • 可能发生内存泄漏的地方有哪些?

1、内部类引用导致Activity的泄漏

在Java中,非静态(匿名)内部类会默认隐性引用外部类对象。而静态内部类不会引用外部类对象。

最典型的场景是Handler导致的Activity泄漏,如果Handler中有延迟的任务或者是等待执行的任务队列过长,

都有可能因为Handler继续执行而导致Activity发生泄漏。

为了解决这个问题,可以在UI退出之前,执行remove Handler消息队列中的消息与runnable对象。

或者是使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。

举例,MainTabActivity - MainTabHandler:

如何修复?

Android Weak Handler:可以避免内存泄漏的Handler库,参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1123/2047.html

2、Activity Context被传递到其他实例中,这可能导致自身被引用而发生泄漏。

考虑使用Application Context而不是Activity Context。

例如:全局Dialog或者Context被单例持有。

3、静态造成的内存泄漏

4、还有静态变量持有View,例如:

private static View view;

void setStaticView() {

view = findViewById(R.id.sv_button);

}

5、注意监听器的注销(稍后利用工具分析一个例子)

regist就要unregist

6、注意Cursor对象是否及时关闭(项目中也存在,不再列举)

7、WebView的引起的泄漏(暂时没有研究)

  • 使用工具分析定位解决内存泄漏

1、Memory monitor

通过MemoryMonitor可以看到,启动手雷进入手雷的内存情况如下(为什么没有做任何操作内存一直在增加?):

通过实例分析一处内存泄漏,操作步骤如下:

启动手雷 - 进入首页 - 切换底部tab到我的tab - 点击登录弹窗弹窗 - 登录成功返回首页

2、MAT(Memory Analyzer Tool)

需要下载MAT独立版,可到这里下载解压使用:192.168.8.188上传2ltsoft

分析刚才的操作内存情况

进入首页并没有进行任何活动操作,为什么会有那么多bitmap对象呢?

3、LeakCanary

LeakCanary 中文使用说明,参考:https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

LeakCanary:让内存泄露无所遁形,参考:https://www.liaohuqiu.net/cn/posts/leak-canary/

4、TraceView(不做详细分析)

5、GT(应该更适合测试同学测试APP性能)

利用GT,仅凭一部手机,无需连接电脑,您即可对APP进行快速的性能测试(CPU、内存、流量、电量、帧率/流畅度等等)、

开发日志的查看、Crash日志查看、网络数据包的抓取、APP内部参数的调试、真机代码耗时统计等。

GT官网:http://gt.qq.com/index.html

  • 内存使用策略优化

1、看看下载一个视频加上浏览一下精选页,然后将应用切到后台,内存使用情况

2、有什么优化内存的策略

A、onLowMemory():Android系统提供了一些回调来通知当前应用的内存使用情况,通常来说,当所有的background应用都被kill掉的时候,forground应用会收到onLowMemory()的回调。在这种情况下,需要尽快释放当前应用的非必须的内存资源,从而确保系统能够继续稳定运行。

B、onTrimMemory(int):Android系统从4.0开始还提供了onTrimMemory()的回调,当系统内存达到某些条件的时候,所有正在运行的应用都会收到这个回调,同时在这个回调里面会传递参数,代表不同的内存使用情况,收到onTrimMemory()回调的时候,需要根据传递的参数类型进行判断,合理的选择释放自身的一些内存占用,一方面可以提高系统的整体运行流畅度,另外也可以避免自己被系统判断为优先需要杀掉的应用。

  • 文章推荐:

1、Android内存优化之OOM:http://hukai.me/android-performance-oom/

2、内存泄露从入门到精通三部曲之基础知识篇:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=21&extra=page%3D4

3、内存泄露从入门到精通三部曲之排查方法篇:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=62&extra=page%3D5

4、内存泄露从入门到精通三部曲之常见原因与用户实践:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=125&highlight=%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/862548.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号