安卓系列之性能知识点

226 阅读4分钟

安卓系列之性能知识点

GC

Garbage Collector,垃圾回收机制。

内存抖动

Memory Churn,短时间内有大量的对象被创建或者被回收的现象。

优化方案

  1. 不在循环内创建新对象。
  2. 不要在自定义 View 的 onDraw()方法内频繁创建对象。
  3. 当需要大量使用 Resource 的时候,缓存在数组中实现复用。
  4. 对于能够复用的对象,可以利用缓存机制。

内存泄漏

程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

LeakCanary

内存泄漏检测工具 APP

如何检测

通过一个弱引用(WeakReference)和一个引用队列(ReferenceQueue)检测对象是否被 GC 回收成功,判断条件是弱引用所引用的对象被 GC 回收后,虚拟机会把这个弱引用加入与之关联的引用队列中,然后查询这个对象是否被 GC 回收成功。

流程

  • 对象添加到监控列表

  • GC 扫描回收

  • 从引用队列中获取引用

  • 判断是否回收成功

    • 是,从监控列表中转移到保留列表中
    • 否,从监控列表中移除

AMS

ActivityManagerService,管理 Activity 的创建和销毁。

场景

  1. 单例
    单例引用上下文导致内存泄漏,可以使用全局上下文替代。
  2. 静态变量
    静态对象使用上下文导致内存泄漏,可以使用全局上下文替代。
  3. 非静态内部类
    例如:在 Activity 创建 Handler 匿名内部类。
  4. 没有取消的注册或者回调
    例如:广播和 eventbus。
  5. Timer 和 TimerTask
    定时器
  6. 资源未释放
    例如:IO 流,File 流等。
  7. 属性动画
    在 Activity 或者 Fragment 销毁的时候暂停并销毁。
  8. Webview
    需要在 Activity 的 onDestory()方法中从父容器移除且销毁 Webview 来解决。

OOM

OOM(内存溢出) 可以通过性能工具进行观察定位问题。

归属

OOM 属于 Error 错误,非 Exception 错误。

案例

  1. 大图加载
  2. 内存泄漏

图片压缩

  1. 质量压缩
    改变位深和透明度进行压缩。使用 Bitmap.compress()。
  2. 尺寸压缩
    两次 decode,使用 Bitmap.option()。
  3. Native 压缩
    使用 libjpeg.so 库(哈夫曼算法)。

UI 优化

优化方案

  1. 优先使用 LinearLayout 和 FrameLayout,减少使用 RelativeLayout。
  2. 减少重叠颜色的填充。
  3. 使用 include 和 merge 增加复用。
  4. ViewStub 按需加载,更加轻便。
  5. 复杂界面优先使用 ConstraintLayout。
  6. Activity 内的动画效果在 onDestory()方法中 cancel。
  7. 不要在自定义 View 的 onDraw()方法内做耗时操作。

检测工具

  1. 开发者-> 调试 GPU 过度绘制 -> 红色区域均是绘制过度
  2. 开发者-> 监控 -> GPU 呈现模式-> 在屏幕上显示为条形图 -> 超过红色警戒线的即是超过 16ms 绘制时长

启动速度优化

启动方式

  1. 冷启动 指应用程序从头开始。
  2. 暖启动 包含了冷启动时发生的一些操作,减少了对象初始化、布局加载等工作,启动时间更短。
  3. 热启动 把 Activity 带到前台。

时间对比

冷启动 > 暖启动 > 热启动

优化方案

  1. 去除开屏页,使用 theme 加载开屏效果。
  2. 优化减少网络请求完才可以进入主页。
  3. 避免在 Application 中做耗时操作。

包体积优化

  1. lint 工具删除不需要的资源文件。
  2. 打包开启资源压缩和自动删除无用资源。
shrinkResources true
minifyEnabled true
  1. 少用切图,使用 shape 实现效果,例如按钮背景。
  2. 同一张图,可以使用动画去实现不同状态,例如展开和收起的三角按钮。
  3. 利用 TinyPNG 等第三方压缩网站对图片进行压缩处理。
  4. 混淆打包。
  5. 插件化。

耗电优化

  1. JobScheduler 任务调度,在系统某些特定情况下对数据进行处理,例如电量变化的时候进行数据上传等。

其他优化

  1. 耗时操作不要在主线程中。
  2. 使用线程的时候需要配合线程池。
  3. 使用 Analyze->Inspect Code 进行代码优化。

若帅哥美女对该系列文章感兴趣,可微信搜索公众号(木子闲集)关注更多更新文章哦,谢谢~