Android性能优化学习之笔记

Android性能优化之内存优化

  • 垃圾回收机制:在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。

  • 内存抖动:内存抖动是因为在短时间内大量的对象被创建又马上被释放。瞬间产生大量的对 象会严重占用Young
    Generation的内存区域,当达到阀值,剩余空间不够的时候,会触发GC从而导致刚产生的对象又很快被回收。即使每次分配的对象占用了很少的内存,

    但是他们叠加在一起会增加Heap的压力,从而触发更多其他类型的GC。这个操作有可能会影响到帧率,并使得用户感知到性能问题。

1、内存检测工具:

1.1 Memory Monitor:

  如果你在Memory Monitor里面查看到短时间发生了多次内存的涨跌,这意味着很有可能发生了内存抖动。
使用它的特点在于:

  1. 方便显示内存使用和GC情况;
  2. 快速定位卡顿是否和GC有关;
  3. 快速定位Crash是否和内存占用过高有关;
  4. 快速定位潜在的内存泄漏问题;
  5. 简单易用;
  6. 不能准确定位问题。不能准确定位问题。
1.2 Allocation Tracker

 使用其的特点在于:

  • 定位代码中分配的对象类型,大小,时间,线程,堆栈等信息;
  • 定位内存抖动问题;
  • 配合HeapView一起定位内存泄漏问题; 配合HeapView一起定位内存泄漏问题;
  • 使用复杂使用复杂
1.3 Heap View

  下图演示了Android Tools里面的Heap Viewer的功能,我们可以看到当前进程中的Heap Size的情况,分别有哪些类型的数据,占比是多少。
Heap View演示
 而常见的内存泄漏问题:

  • 单例造成的泄漏
    这里写片描述

  • 非静态内部类的静态实例造成的泄漏
    这里写图片描述
    避免方法:
    1- 尽量不要让静态变量引用Activity;
    2 - 使用WeakReference
    3 - 使用静态内部类来代替内部类
    4 - 静态内部类使用弱引用来引用外部类
    5 - 在声明周期结束的时候释放资源。

2 Android性能优化之视图优化

  大多数手机的屏幕刷新频率是60hz,如果在1000/60=16.67ms内没有办法把这一帧的任务执行完毕,就会发生丢帧的现象。丢帧越多,用户感受到的卡顿情况就越严重。
这里写图片描述
渲染操作通常依赖于两个核心组件:CPU与GPU。CPU负责包括Measure,Layout,Record,Execute的计算操作,GPU负责Rasterization(栅格化)操作。CPU通常存在的问题的原因是存在非必需的视图组件,它不仅仅会带来重复的计算操作,而且还会占用额外的GPU资源。

  在Android里面那些由主题所提供的资源,例如Bitmaps,Drawables都是一起打包到统一的Texture纹理当中,然后再传递到GPU里面,这意味着每次你需要使用这些资源的时候,都是直接从纹理里面进行获取渲染的。当然随着UI组件的越来越丰富,有了更多演变的形态。例如显示图片的时候,需要先经过CPU的计算加载到内存中,然后传递给GPU进行渲染。文字的显示比较复杂,需要先经过CPU换算成纹理,然后交给GPU进行渲染,返回到CPU绘制单个字符的时候,再重新引用经过GPU渲染的内容。动画则存在一个更加复杂的操作流程。
为了能够使得App流畅,我们需要在每帧16ms以内处理完所有的CPU与GPU的计算,绘制,渲染等等操作。

  Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的UI结构里面,如果不可见的UI也在做绘制的操作,会导致某些像素区域被绘制了多次。这样就会浪费大量的CPU以及GPU资源。当设计上追求更华丽的视觉效果的时候,我们就容易陷入采用复杂的多层次重叠视图来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能,我们必须尽量减少Overdraw的情况发生。

  1. Google提供show GPU overdraw开发者选项,来提供对屏幕过度绘制的监测
    这里写图片描述
    蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

  2. google还在开发者选项中提供了GPU Profiler选项,通过分析柱状图来判断出屏幕出现卡顿现象的原因。
    那么如何避免UI卡顿现象呢:
    a. 避免在onDraw中创建对象——对象池
    b. 减少View层级
    c. 避免在UI顶层使用RelativeLayout——measure两次
    d. 自定义控件控制绘制的复杂度。

    如何优化过度绘制:
    降低View层级;去掉不必要的背景(eg:去掉windows默认的背景);ViewStub;.9图的用作背景。

3 Android性能优化之电量优化

  手机各个硬件模块的耗电量是不一样的,有些模块非常耗电,而有些模块则相对显得耗电量小很多。电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情。唯一可行的方案是使用第三方监测电量的设备,这样才能够获取到真实的电量消耗。往往只有25%~30%的电量是耗在核心功能上,而剩下的大多数75%左右的电量是用在别的(如上传统计数据、检查位置信息、论调服务器,拉取广告信息等)方面。 而电量消耗又大致可以分为以下三块:网络,WeakLock,非及时的任务。

  使用WakeLock或者JobScheduler唤醒设备处理定时的任务之后,一定要及时让设备回到初始状态。每次唤醒蜂窝信号进行数据传递,都会消耗很多电量,它比WiFi等操作更加的耗电。所以网络优化是优化电量的一种有力手段。
- Full power: 能量最高的状态,移动网络连接被激活,允许设备以最大的传输速率进行操作
- Low power: 一种中间状态,对电量的消耗差不多是Full power状态下的50%。
- Standby: 最低的状态,没有数据连接需要传输,电量消耗最少
这里写图片描述
总之,为了减少电量的消耗,在蜂窝移动网络下,最好做到批量执行网络请求,尽量避免频繁的间隔网络请求。

  通过前面学习到的Battery Historian我们可以得到设备的电量消耗数据,如果数据中的移动蜂窝网络(Mobile Radio)电量消耗呈现下面的情况,间隔很小,又频繁断断续续的出现,说明电量消耗性能很不好:
这里写图片描述
经过优化之后,如果呈现下面的图示,说明电量消耗的性能是良好的:
这里写图片描述
另外WiFi连接下,网络传输的电量消耗要比移动网络少很多,应该尽量减少移动网络下的数据传输,多在WiFi环境下传输数据。
这里写图片描述

  使用Job Scheduler,应用需要做的事情就是判断哪些任务是不紧急的,可以交给Job Scheduler来处理,Job Scheduler集中处理收到的任务,选择合适的时间,合适的网络,再一起进行执行。数据压缩,虽然会增加文件压缩方面的的耗时耗电,但是相较于来说,还是极大的减少了。、

4 Android性能优化只Bitmap优化

  • 图片复用

    常见的图像存储格式有jpg、png、webp,如今更推荐使用webp格式的,Android中要显示图片必须经过解码(decode)读取图像的数据到内存中,BitmapFactory提供了常用的一些decode方法,图片真正占用的内存大小要看decode之后的数据大小。运用Memory Heap机制使缓存区的图片能得到二次利用从而减少内存抖动现象发生的几率; 使用 Object Pool 分配内存块,可以把对象池分类成不用的图片格式区。glide提供了很好的图片管理。

  • 预压缩图片

    通过对图片的压缩预览。BitmapOption.inSanmpleSize指定图片缩小倍数,但是只能缩放2的幂次方,而inScaled可以是任意倍数,通常先通过前者进行2的幂次缩放,再用后者来处理可以极大的提高图片效率。

  • 减少字节数

    根据自己的需求采用不同的图片格式来显示图片,以及图片文件的大小进行裁减。从而达到有效的较少字节数的目的。

  • LRU cache

    采用LRU原则,实现一个对图像内存存储的读取删除方式,是图片达到复用的效果。

其他

  • Profiling:

    该工具可以帮助我们在程序运行的时候收集每个方法消耗的时间。

  • Lint Tool:

    对JAVA代码进行检查,帮助您轻松地识别并纠正问题与结构质量的代码,而不必执行应用程序或编写任何测试用例。每个问题检测到该工具报告的一个描述消息和严重性级别,您可以快速地优先考虑的关键改进,需要。您还可以配置一个问题的严重性级别,忽略不相关的问题,为您的项目,或提高的严重程度。这个工具有一个命令行接口,所以您可以很容易地集成到您的自动化测试过程。这个 lint工具检查你的Android项目源文件潜在的bug和优化改进,以确保正确性、安全性、性能、可用性、可访问性和国际化。您可以运行 lint从命令行或从Eclipse环境。

  • 使用轻量容器

    使用SparseBoolMapdcf和代替HashMap.

  • 枚举类型的优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值