服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-10-20 更新于 2026-10-20 简米科技 3,589 字 8 分钟阅读

Android虚拟机与Java如何协同运行?核心机制是什么

导读Android虚拟机与Java的协同运行,核心答案是:Java源码编译为class文件后,Android工具链会将其转为dex字节码,由Android虚拟机(ART)负责解释执行或编译为机器码,而Java语言自身的特性(面向对象、自动内存管理)则通过虚拟机的运行时组件来完成落地,这套机制让Android应用能跨……

Android虚拟机与Java的协同运行,核心答案是:Java源码编译为class文件后,Android工具链会将其转为dex字节码,由Android虚拟机(ART)负责解释执行或编译为机器码,而Java语言自身的特性(面向对象、自动内存管理)则通过虚拟机的运行时组件来完成落地。这套机制让Android应用能跨设备运行,同时保证性能和资源可控。

从Java源码到安卓应用的旅程

Java代码并非直接被Android系统读取,Android环境中的Java,其实经过了两次"翻译"。

第一站,JDK编译器(javac)会把.java文件编译成.class文件,里面是JVM认识的字节码,但Android无法直接执行标准JVM字节码,于是下一站交给Android SDK中的d8工具(旧版是dx工具),它把.class文件合并重排,转成单个.dex文件,dex格式的诞生,是为了适配移动端的内存和CPU限制,它把多个class文件的冗余常量合并,体积更小。

打包进APK后,应用安装到手机,此时Android虚拟机(5.0+是ART,5.0前是Dalvik)正式接管,开始对dex字节码进行"二次加工"。

ART虚拟机的双引擎策略:JIT与AOT

ART虚拟机的工作方式,业界常形容为"先快后稳",它内部有两套执行引擎,协同完成Java代码的运行。

JIT编译:让应用快速启动

Android 7.0引入JIT(Just-In-Time)机制,应用首次启动或运行热点代码时,ART会启动即时编译,把频繁执行的dex字节码翻译成机器码,JIT的优点是启动快,只编译用到的代码,不浪费编译时间,但它也有代价,就是每次运行都要现场翻译,CPU开销存在。

一个电商应用启动时,ART会先JIT编译首页加载的核心路径,让用户快速看到界面,JIT编译的代码,会在特定条件下被记录到profile文件中。

AOT编译与dex2oat的实际应用

AOT(Ahead-Of-Time)发生在应用安装或系统空闲时。dex2oat(dalvik exec to optimized art)进程会把dex字节码预先编译成OAT文件(ART的私有格式),本质是机器码加dex源码的混合体。

Android虚拟机与Java如何协同运行?核心机制是什么

系统执行AOT编译,会根据用户使用习惯和JIT生成的profile,优先编译高频代码块,这套"混合编译模式"(JIT+Profile+AOT)从Android 7.0开始成熟,到Android 9.0又加入了AOT编译的网络下载策略,减少了安装时间。

JIT与AOT的侧重点:

  • JIT:内存占用高但启动快,适合冷启动阶段
  • AOT:编译后执行快,适合高频调用路径
  • 配合机制:后台空闲且充电时,ART会对已收集profile的应用执行AOT重编译

ART对Java内存管理的改造

Java程序员习惯new对象而不用管释放,这个"内存安全"承诺,在Android上由ART的垃圾回收器(GC)来实现,但移动端内存比服务器小得多,ART做了不少本地化调整。

Mark-Compact与Concurrent GC的协同

早期Dalvik使用Mark-Sweep算法,会产生大量内存碎片,ART则引入了Mark-Compact算法,在GC时把存活对象整理到连续内存区,减少碎片化,ART的并发GC(CMS)允许大部分标记阶段和应用线程并行执行,减少了卡顿。

从Android 8.0开始,ART还加入了并发复制(Concurrent Copying)GC,它能够在应用线程持续运行的情况下搬运对象,进一步削减GC停顿,据业内专家观点,这种GC设计借鉴了工业级JVM的经验,但针对移动端暂停时间做了深度定制。

为大对象堆开启的额外通道

Java里的Bitmap是内存大户,ART为Bitmap专门划出"图形堆"(Graphics Heap),不占用普通Java堆,但Bitmap的像素数据需要Native内存,这部分由C++代码管理,容易泄漏,因此开发者需要记得调用Bitmap.recycle()或依赖ByteBuffer机制来手动释放底层资源。

ART与标准JVM的五大差异

许多从后端转Android的开发者有困惑:JVM和ART到底哪里不一样?表里可以一图看清:

  • 字节码格式:JVM读取class文件,ART读取dex文件,dex更紧凑
  • 编译策略:JVM多用解释器+分层编译,ART默认开启AOT混编
  • Android虚拟机与Java如何协同运行?核心机制是什么

  • 内存模型:JVM运行在64位服务端,堆可配置大容量;ART受系统内存管理约束,堆上限由dalvik.vm.heapsize决定
  • 线程模型:JVM线程直接映射内核线程,ART线程调度同样基于Linux线程,但优先级更激进
  • 调试接口:JVM使用JDWP协议,Android使用jdwp,但需要开启ro.debuggable才能附加调试进程

这种差异带来的实际后果是:你不能把Java后端项目直接丢到Android上跑,需要适配Android API和资源管理环境。

Java虚拟机在安卓生态中的角色演变

随着时间推移,ART对Java的处理也在收敛。

从Dalvik到ART:解释器时代的终结

Android 5.0之前是Dalvik,纯解释执行,性能被iOS的Objective-C原生编译甩开,ART在Android 4.4上实验,5.0正式默认,彻底改变了Java代码的运行轨迹,一开始用全量AOT,安装时全编译,应用安装很慢,后来加入JIT和Profile引导编译,安装时间大幅回降。

对开发者意味着什么

Google官方文档指出,ART是Android运行时的主要实现,开发者无需关心JIT或AOT细节,只需写出高效的Java/Kotlin代码,但了解底层原理,能帮助你排查一些疑难问题。

一个应用在低配置手机上卡顿,可能是AOT编译没有覆盖到用户常用路径,此时开发者可以在Google Play控制台看启动基础剖析报告,或者用adb shell dumpsys dalvikvm查看当前运行模式和GC统计。

Java 17语言特性在Android的可得性

Android对Java语言版本的支持,依赖Android Gradle Plugin和工具链。AGP 8.x支持Java 17语法,但核心的desugaring(脱糖)机制,会把新语法转换为低版本API兼容的形式,开发中可以放心的用record、sealed class等写法,但最终执行仍是ART能理解的字节码形式。

ART从本质上讲,是一个为了续航和内存而优化的Java虚拟机

Android虚拟机与Java如何协同运行?核心机制是什么

,它和Java的协同,既保留了跨平台、面向对象、自动内存管理的语言优势,又通过JIT/AOT混合编译和特定GC算法,适配了移动端特有的资源桎梏,对开发者而言,理解这套协同机制,意味着你能在写出可靠代码的同时,准确判断哪些性能问题瓶颈出现在Java层、哪些出现在虚拟机层,从而找到真正的优化路径。

Q&A:Android虚拟机与Java协同运行的常见疑问

Android虚拟机如何工作?

Android虚拟机指ART,它负责运行apk中的dex字节码,安装时dex2oat可能把部分代码预编译为OAT文件,运行时JIT对剩余热点代码即时编译,ART在Java内存模型之上,实现了对垃圾回收、线程同步和异常处理的运行时支持,是Java程序能跑在手机上的直接原因。

为什么Android用Java代码而不是直接用C++语言每次获取更好的性能?

因为Java提供跨平台运行时的便利,开发者只需一次编码,在各种硬件架构(ARM、x86、RISC-V)上都能运行,ART通过AOT把Java代码编译成本地机器码,已经把性能差距缩小到较小范围,只有图形渲染等高频路场景才会看到明显差异,多数业务场景下,Java的代码可维护性和生态资源,远大于底层语言带来的边际性能收益。

小米手机与三星手机上的Android虚拟机有什么区别?

不同厂商几乎不对ART本身做改造,系统层差异更多在于相册、游戏助手等Framework服务的实现,但厂商可以在系统镜像中调整ART参数:

  • 调整堆内存上限
  • 调整后台应用GC策略
  • 调整AOT编译触发时间(例如充电时统一编译)

这些调整会导致同一APK在两台设备上出现运行微观差异,但开发者的Java代码无需修改,设备兼容性由兼容性定义文档(CDD)保证,厂商不能改变虚拟机行为的基础契约。

ART和Java的配合并非一成不变,它随Android版本迭代持续优化,开发者保持对新运行时行为的好奇,是解决疑难性能问题的最佳后盾。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱