Skip to content

Latest commit

 

History

History
235 lines (169 loc) · 6.52 KB

4.App内存优化.md

File metadata and controls

235 lines (169 loc) · 6.52 KB

第4章 App内存优化

4-2 内存优化介绍及工具选择

  1. 内存优化介绍
    1. 内存是大问题但缺乏关注
    2. 压死骆驼的最后一根稻草
  2. 内存问题
    1. 内存抖动:锯齿状、GC导致卡顿
    2. 内存泄漏:可用内存减少、频繁GC
    3. 内存溢出:OOM、程序异常
  3. 优化工具选择
    1. Memory Profiler
      1. 实时图标展示应用内存使用量
      2. 识别内存泄漏、抖动等
      3. 提供捕获堆转储、强制GC以及跟踪内存分配的能力
      4. 方便直观、线下平时使用
    2. Memory Analyzer
      1. 强大的Java Heap分析工具,查找内存泄漏及内存占用
      2. 生成整体报告、分析问题等
      3. 线下深入使用
    3. LeakCanary
      1. 自动内存泄漏检测
      2. https://github.com/square/leakcanary
      3. 线下集成

4-3 Android内存管理机制

  1. Java内存管理机制

    1. Java内存分配

      1. 方法区、虚拟机栈、本地方法栈、堆、程序计数器
    2. Java内存回收算法

      1. 标记-清除算法

        效率和清除效率不高

        产生大量不连续的内存碎片

        1. 标记出所有需要回收的对象
        2. 统一回收所有被标记的对象
      2. 复制算法

        实现简单,运行高效

        浪费一半空间,代价大

        1. 将内存划分为大小相等的两块
        2. 一块内存用完之后复制存活对象到另一块
        3. 清理另一块内存
      3. 标记-整理算法

        1. 标记过程与“标记-清除”算法一样
        2. 存活对象往一端进行移动
        3. 清理其余内存
      4. 分代收集算法

        1. 结合多种收集算法优势
        2. 新生代对象存活率低,复制
        3. 老年代对象存活率高,标记-整理
  2. Android内存管理机制

    内存弹性分配,分配值与最大值受具体设备影响

    OOM场景:内存真正不足、可用内存不足

    1. Dalvik与Art区别
      1. Dalvik仅固定一种回收算法
      2. Art回收算法可运行期选择
      3. Art具备内存整理能力,减少内存空洞
    2. Low Memory Killer
      1. 进程分类
      2. 回收收益

4-4 内存抖动解决实战

  1. 内存抖动介绍

    定义:内存频繁分配和回收导致内存不稳定

    表现:频繁GC、内存曲线呈锯齿状

    危害:导致卡顿、OOM

    内存抖动导致OOM:

    1. 频繁创建对象,导致内存不足及碎片
    2. 不连续的内存片无法被分配,导致OOM
  2. 内存抖动解决实战

    1. 使用Memory Profiler初步排查
    2. 使用Memory Profiler或CPU Profiler结合代码排查
    3. 模拟内存抖动代码见:MemoryShakeActivity
  3. 内存抖动解决技巧

    找循环或者频繁调用的地方

4-5 内存泄露解决实战

  1. 内存泄漏介绍

    定义:内存中存在已经没有用的对象

    表现:内存抖动、可用内存逐渐变少

    危害:内存不足、GC频繁、OOM

  2. Memory Analyzer

    1. http://www.eclipse.org/mat/downloads.php
    2. 转换:hprof-conv原文件路径转换后文件路径
    3. 模拟内存泄露代码见:MemoryLeakActivity
  3. 内存泄漏解决实战

    1. 使用Memory Profiler初步观察
    2. 使用Memory Analyzer结合代码确认
    3. 找到内存泄露位置

4-6 全面理解MAT

4-7 ARTHook优雅检测不合理图片

  1. Bitmap内存模型

    1. API10之前Bitmap自身在Dalvik Heap中,像素在Native
    2. API10之后像素也被放在Dalvik Heap中
    3. API26之后像素在Native
  2. 获取Bitmap占用内存

    1. getByteCount
    2. 宽 * 高 * 一像素占用内存
  3. 常规方式

    1. 背景:图片对内存优化至关重要、图片宽高大于控件宽高
    2. 实现:集成ImageView,覆写实现计算大小
    3. 侵入性强
    4. 不通用
  4. ARTHook实战

    1. 挂钩,将额外的代码钩住原有方法,修改执行逻辑

      1. 运行时插桩
      2. 性能分析
    2. Epic简介

      1. Epic是一个虚拟机层面、以Java Method为粒度的运行时Hook框架
      2. 支持Android4.0 - 9.0
      3. https://github.com/tiann/epic
    3. Epic实战

      1. ImageHook.java

      2.         DexposedBridge.hookAllConstructors(ImageView.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        DexposedBridge.findAndHookMethod(ImageView.class, "setImageBitmap", Bitmap.class, new ImageHook());
                    }
                });

    ARTHook 无侵入性,通用性强,兼容问题大,开源方案不能带到线上环境

4-8 线上内存监控方案

  1. 常规方式
    1. 设定场景线上Dump:Debug.dumpHprofData()
    2. 超过最大内存80%线上Dump,回传文件,分析
    3. Dump文件太大,和对象数正相关,可裁剪
    4. 上传失败率高、分析困难
    5. 配合一定策略,有一定效果
  2. LeakCanary
    1. LeakCanary带到线上
    2. 预设泄漏怀疑点
    3. 发现泄漏回传
    4. 不适合所有情况,必须预设坏一点
    5. 分析比较耗时、也容易OOM
  3. LeakCanary原理
    1. 监控生命周期,onDestory添加RefWatcher检测
    2. 二次确认断定发生内存泄漏
    3. 分析泄漏,找引用链
    4. 监控组件+分析组件
  4. LeakCanary定制
    1. 预设怀疑点:自动找怀疑点
    2. 分析泄漏链路慢:分析Retain size大的对象
    3. 分析OOM:对象裁剪,不全部加载到内存
  5. 线上监控完整方案
    1. 待机内存、重点模块内存、OOM率
    2. 整体及重点模块GC次数、GC时间
    3. 增强的LeakCanary自动化内存泄漏分析

4-9 内存优化技巧总结

  1. 优化大方向
    1. 内存泄漏
    2. 内存抖动
    3. Bitmap
  2. 优化细节
    1. LargeHeap属性
    2. onTrimMemory:系统低内存回调
    3. 使用优化过的集合:SparseArray
    4. 谨慎使用Shared Preference
    5. 谨慎使用外部库
    6. 业务架构设计合理

4-10 内存优化模拟面试

  1. 你们内存优化项目的过程是怎么做的
    1. 分析现状、确认问题
      1. 线上OOM率
      2. AS 内存监控抖动频繁
    2. 针对性优化
  2. 你做了内存优化最大的感受是什么
    1. 磨刀不误砍柴工
    2. 技术优化必须结合业务代码
    3. 系统化完善解决方案
  3. 如何检测所有不合理的地方
    1. ARTHook
    2. 重点强调区别