Android应用程序与运行环境
Android应用程序与运行环境 JVM(Java Virtual Machine)、Dalvik 和 ART(Android Runtime)从广义上来说,都可以归类为 "Java 运行时环境" (Java Runtime Environment)的一部分,核心目标是执行 Java 字节码或类似 Java 的程序。
本文目录 13 个章节
Android应用程序与运行环境
JVM(Java Virtual Machine)、Dalvik 和 ART(Android Runtime)从广义上来说,都可以归类为 "Java 运行时环境"(Java Runtime Environment)的一部分,核心目标是执行 Java 字节码或类似 Java 的程序。
Dalvik 和 ART可以看作是针对 Android 平台优化的 Java 虚拟机变种,旨在支持 Java 生态和语言特性,负责解释、编译和运行 Java 或 Kotlin 代码(在 Android 中)。
JVM(Java Virtual Machine)
JVM 是一种运行 Java 字节码(.class 文件)的虚拟机,作为 Java 平台的核心组件。它提供了一种跨平台的运行环境,使 Java 程序能够在多种操作系统上运行。
工作原理
- Java 字节码:Java 源代码(
.java文件)通过编译器javac转换为.class文件(Java 字节码)。 - 加载与解释:JVM 通过类加载器(ClassLoader)加载
.class文件,并将其转换为虚拟机可以执行的指令。 - 执行方式:
- 解释执行:逐行解释
.class文件中的字节码并执行。 - JIT(Just-In-Time)编译:将热点代码(频繁执行的代码)编译为本地机器码,提高性能。
- 解释执行:逐行解释
特点
- 跨平台性:Java 程序可以在任何安装了 JVM 的系统上运行。
- 面向通用场景:JVM 的设计初衷是服务于多种环境和设备。
Dalvik
Dalvik 是 Android 早期的虚拟机,用于在移动设备上高效运行 Android 应用程序。它能够运行 Android 专用的 .dex 文件(Dalvik Executable)。
工作原理
- 字节码格式:
- Android 开发中的
.class文件会被转换为.dex文件,这是一种经过优化的字节码格式。
- Android 开发中的
- 基于寄存器的架构:
- 不同于 JVM 基于栈的指令集,Dalvik 使用寄存器作为操作数存储区。这种方式减少了指令数量,提高了执行效率。
- 解释执行:
- Dalvik 主要通过解释器逐行执行
.dex字节码。
- Dalvik 主要通过解释器逐行执行
特点
- 为移动设备优化:
- 低内存占用。
- 更高效的指令集。
- 单独进程模型:
- 每个 Android 应用都有自己的 Dalvik 实例,运行在独立的进程中。
- GC(垃圾回收)优化:
- 针对低内存设备进行了垃圾回收算法优化。
ART(Android Runtime)
ART 是 Android 的现代运行时,作为 Dalvik 的替代者,从 Android 5.0(Lollipop)开始成为默认运行时。ART 的目标是进一步提高性能,优化资源使用。
工作原理
- AOT(Ahead-Of-Time)编译:
- 在应用安装时,ART 会将
.dex文件编译为本地机器码(ELF文件),这样在运行时无需解释或即时编译。
- 在应用安装时,ART 会将
- JIT(Just-In-Time)编译:
- 从 Android 7.0 开始,ART 增加了 JIT 编译器,用于在运行时优化热点代码。
- 解释执行:
- ART 也支持解释执行未编译的代码。
特点
- 高性能:
- AOT 编译减少了运行时的计算开销,启动速度更快。
- 优化内存使用:
- ART 支持共享类和字符串池,减少了重复数据的内存占用。
- 改进的垃圾回收:
- ART 提供了更高效的垃圾回收机制(如并行 GC 和增量 GC)。
- 调试和分析支持:
- 支持更精细的调试功能,例如更好的堆栈跟踪和内存泄漏检测。
DEX( Dalvik Executable) 是 Android 平台的一种字节码格式。 A bytecode format designed specifically for Android that's optimized for a minimal memory footprint.
所有 Android 应用程序的代码最终都会以 DEX 文件的形式运行在 Android Runtime (ART) 或 Dalvik 虚拟机上。
特点
- DEX 文件的设计目标是减少运行时的内存使用。
- 指令集被精简并优化,以适应移动设备的有限资源。
- 不同于 Java 的
.class文件(每个类一个文件),一个 DEX 文件可以包含多个类的字节码。这种设计减少了文件数量和存储开销。
- 虽然 DEX 文件是为 Android 优化的,但它仍然保持了平台无关性,类似于 JVM 的字节码。
构建
在构建 APK 的过程中,所有 JAR 文件中的 Java 字节码会被 d8 或 dx 工具转换为 DEX 格式。
JAR文件中包含的是标准的 Java 字节码(.class文件)。- 在构建时,这些
.class文件会被统一合并并转换为一个或多个.dex文件。 - 最终生成的 DEX 文件会被打包到 APK 的
classes.dex文件中。
Unity 在构建 Android 工程时,会将所有 JAR 插件统一传递给 Android 构建工具链(Gradle 或
UnityPlayerActivity的构建脚本),最终处理方式取决于这些工具链: - 普通 JAR 文件:字节码会被转换为 DEX。 - 动态加载 JAR 文件:如果指定为动态加载,JAR 会保留原始形式。
加载和执行
- 加载 DEX 文件 DEX 文件通常通过虚拟机加载和解释。加载器主要包括:
ClassLoader:加载和解析 DEX 文件中的类。DexClassLoader:支持在运行时动态加载外部的 DEX 文件。
- 解释与编译
- 解释执行:ART 和 Dalvik 虚拟机可以直接解释 DEX 字节码。
- 编译执行:
- 在 ART 中,常见方法会被 JIT 编译为本地机器码。
- 在应用安装时,ART 会将 DEX 文件通过 AOT 编译为本地代码。
相关工具
- d8:
- 新版的字节码转换工具,用于将
.class转换为.dex。 - 比
dx更高效,支持增量编译。
- 新版的字节码转换工具,用于将
- dexdump:
- 用于分析和查看 DEX 文件内容的工具。
- proguard:
- 用于混淆代码,减小 DEX 文件的大小,并保护代码不被反编译。