热修复预备知识

前期预备知识

dex/class

  1. class文件结构解析
    • 什么是class文件?java

      可以被jvm识别,加载并执行的文件格式android

    • 如何生成一个class文件算法

      • [x] 经过IDE自动帮咱们build
      • [x] 手动经过javac 去生成class文件
        PS: 如何制定jdk版本生成字节码文件呢?—>javac -target 1.6 -source 1.6 HelloWorld.java
      • [x] 经过java命令去执行class文件
        java com.example.hostfit.Test ps: 执行时根据全类名来执行的
    • class文件的做用 记录类文件的全部信息(记录了this super 等关键字)缓存

    • class文件结构及格式(宏观) class文件结构安全

      • 一种八位字节的二进制流文件
      • 各个数据按照顺序紧密排列,无间隙
      • 每一个类或接口都单独占一个class文件
    • class文件弊端服务器

      • 内存占用大,不适合移动端
      • 堆栈加载模式,加载速度慢
      • 文件IO操做多,类查找慢
  2. dex文件结构解析
    • 什么是dex文件app

      被DVM虚拟机识别,加载并执行的文件格式jvm

    • 如何生成dex文件ide

      • [x] 经过IDE自动帮咱们build生成
      • [x] 手动经过dx命令去生成dex文件
        • javac -target 1.6 -source 1.6 Test.java 生成class文件。ps:指定1.6 版本为了保证兼容
        • dx --dex --output=Test.dex com/example/hostfit/Test.class ps: 是根据全类名来找的
      • [x] 手动运行dex文件在手机上
        • 将dex文件push 到手机存储卡中 adb push Test.dex '手机路径(例如:/sdcard)'
        • dalvikvm -cp Test.dex com.example.hostfit.Test ps: 注意全类名
    • dex文件的做用ui

      记录整个工程中全部类文件的信息。

    • dex文件结构、格式的详解 dex文件结构

      • 一种八位字节的二进制流文件
      • 各个数据按照顺序紧密排列,无间隙
      • 整个应用中全部的java源文件都放在一个dex文件中 ps: 不考虑android 官方提供的multidex
  3. class 与 dex 文件对比 class 与 dex异同
    • 本质上他们都是同样的,dex文件从class文件演变而来
    • class文件存在许多冗余信息(一个类就有一个常量池),而dex文件会去除冗余,并进行整合

jvm/dvm/art 三种虚拟机

  1. java 虚拟机结构解析

    • jvm总体结构

    jvm 结构

    • java代码的编译和执行过程

      • 代码编译过程 编译流程

      • 执行过程 加载流程 1. Loadding :类的信息从文件中获取而且载入到JVM内存中 2. Verrifying: 检查读入的结构是否符合JVM规范的描述 3. Preparing: 分配一个结构用来存储类信息 4. Resolving: 把这个类的常量池全部的符号引用改变成直接引用 5. Initializing: 执行静态初始化程序,把静态变量初始化指定的值

    • Java 内存管理

      • Java 栈区

        用来存放Java方法执行的全部数据 ps: method call-> a -> b - c;栈区由栈帧组成,一个栈帧表明一个方法的执行。

        那什么是栈帧呢?每个方法从调用到执行完成就对应一个栈帧在虚拟机中入栈到出栈。每个栈帧包括局部变量表、栈操做数、动态连接、方法出口。例如(StackOverFlow异常)

        本地方法栈:和Java方法栈一模一样,只不过本地方法栈是专门为Native方法服务的

      • 方法区

        存储被虚拟机加载的类信息,常量,静态变量,便是编译器后等数据,用于占据内存的

      • Java堆

        全部经过New建立的对象的内存都在堆中分配,是虚拟机中最大的一块内存,是GC 要回收的部分

        Java 堆区内存

        1. Young Generation : 刚刚New出来的对象
        2. Old Generation: 当Young Generation 中内存空间不足的时候,就会将Young Generation 中的对象按照必定的算法、规则等存放到Old Generation, 这样 Young Generation 就能够继续分配内存,当二者都没有剩余的空间的时候,就会发生OOM异常,垃圾回收器主要针对这两块内存区域,
        3. Permanent Generation: Java8 已经移除

        特色:Young Old Generation 能够动态分配,当咱们的服务器处理的是及时通信相关服务,就能够将Young Generation内存区域调整大一些;当咱们不须要频繁去建立对象的时候,能够将Young Generation 内存区域调整小一些,这样达到内存对象常驻的效果

    • Java 内存回收机制

      1. 垃圾回收算法

        • 引用计数算法

          缺点:互相循坏引用 ,两个对象不可达,可是GC依然不会回收

        • 可达性算法

          Java 堆区内存

      2. 引用类型

        强引用、弱引用、软引用、虚引用

      3. 如何回收垃圾

        • 标记-清除算法

          Java 堆区内存 优势: 内存块不须要进行对象移动,存活对象比较多的时候,高效; 缺点: 容易形成内存碎片,不利于后续对象的分配

        • 复制算法

          Java 堆区内存 优势:存活的对象比较少,比较高效 缺点:成本须要一块内存做为交换空间

        • 标记-整理算法

          Java 堆区内存 优势: 解决内存碎片问题 缺点: 成本较高一点

      4. 触发回收机制

        • [x] Java虚拟机没法再为新的对象分配内存空间
        • [ ] 手动调用System.gc() 强烈不推荐
        • [x] 低优先级的GC线程,被Jvm 启动了,执行GC
  2. Dalvik 与 jvm的不一样

    • 执行的文件不一样 一个是dex 一个是class文件
    • 类加载的系统(ClassLoader)与JVM的区别比较大
    • jvm 只能同时存在一个,DVM能够同时存在多个
    • DVM 是基于寄存器的(运行更快),JVM 是基于栈的
  3. ART比Dalvik有哪些优点

    • DVM 使用的是JIT来将字节码转换成机器码(每次运行),效率低
    • ART 是采用AOT的预编译技术(安装的时候就将字节码转换成机器码存储于介质中,不须要每次进行转换),执行速度更快
    • ART 会占用更多的应用安装时间和存储空间(以空间换时间)

class loader(Java Android)

类是如何加载到虚拟机的?

  1. Java 中的ClassLoader回顾

    Java ClassLoader 具体回顾 -> java代码的编译和执行过程

  2. Android中ClassLoader 做用详解

    • Android ClassLoader的种类

      • BootsClassLoader

        用来加载Android framework层的一些dex文件

      • PathClassLoader

        用来加载已经安装到系统中的apk文件中的dex文件

      • DexClassLoader

        用来加载指定目录中dex文件

      • BaseDexClassLoader

        是PathClassLoader DexClassLoader 的父类

      一个App至少须要BootClassLoader 和PathClassLoader

    • Android ClassLoader 的特色

      • 双亲代理模型特色

        当前的classLoader去加载此类,若是当前此类已经被ClassLoader加载过就再也不加载,直接返回; 若是未加载,便会查询它的Parents 是否加载过此类,若是加载过 就返回parents加载过的字节码文件; 若是整个继承线的都没有加载过此类,便会子类真正的加载,提升类加载效率。这样就会带来如下两个做用

      • 类加载的共享功能 一些FrameWork层级的类 ,一旦被顶层的classLoader加载过,那么它就会缓存到内存里面,之后任何地方用到,就不用从新加载了

      • 类加载的隔离功能 不一样继承路线上的ClassLoader 加载的类不是同一个类,避免开发者本身写一代码伪形成系统的类库来访问咱们系统可见成员变量。例如:系统层级的类通常初始化的时候就会加载,好比java.lang.String, 应用程序启动以前就会被系统加载,若是在一个app里面写一个自定String 替换掉java.lang.String 会形成严重的安全问题。判断是不是同一个类判断,除了className packageName 另外还须要是同一个ClassLoader加载的。

    • ClassLoader 源码 (加载流程)

      Java ClassLoader ClassLoader loadClass 首先判断被本身或者双亲加载过,若是未加载过,调用BaseDexClassLoader 的findClass,调用DexPathList findClass ,而且完成将dex文件转换成DexFile ,转换成Elements, 遍历数据,调用DexFile loadClassBinaryName - > native

  3. Android 中动态加载要点?

    • 有许多组件(Activity)类须要注册才能使用
    • 资源动态加载复杂(注册、兼容性)
    • 程序运行的时候须要一个上下文环境
相关文章
相关标签/搜索