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

ART虚拟机原理是什么?底层机制如何实现,运行时编译有何优势?

导读ART虚拟机本质上是将Android应用的执行策略从“运行时解释”转向“安装时预编译”的运行时环境,它把DEX字节码直接翻译成机器码,让应用启动更快、内存管理更高效,聊ART之前,先得说清楚它取代的Dalvik虚拟机,Dalvik时代,应用每次启动时都通过JIT把热点代码编译成机器码,运行速度总是受编译时机拖累……

ART虚拟机本质上是将Android应用的执行策略从“运行时解释”转向“安装时预编译”的运行时环境,它把DEX字节码直接翻译成机器码,让应用启动更快、内存管理更高效。

聊ART之前,先得说清楚它取代的Dalvik虚拟机,Dalvik时代,应用每次启动时都通过JIT把热点代码编译成机器码,运行速度总是受编译时机拖累。行业共识认为,Dalvik的最大瓶颈在于每次冷启动都要重新解释、重新优化,白白消耗大量CPU时间,ART改变了这个节奏。

  • Dalvik采用JIT编译,边运行边编译,启动慢但安装快
  • ART早期采用AOT,安装时编译好,运行时直接执行机器码
  • Android 7.0以后,ART走向“解释器+JIT+AOT”混合模式

从用户体感看,ART上线后差别很明显:同样一部中端手机,升级ART后应用冷启动时间普遍缩短,系统卡顿频率下降,代价是安装时间变长,包体占用空间变大,这个取舍在Android早期版本里相当明显,所以Google后续才补充了混合编译来平衡。

安装阶段的性能代价与回报

如果你用过Android 4.4或更老设备,安装大型游戏时等待的“正在优化应用”就是ART在跑dex2oat,这个阶段的CPU占用和耗电量会明显上升,部分测评显示老设备在安装大型应用时可能需要多等待一段时间,但换来的是每次打开应用的流畅感。

Android 7.0之后,ART在设备空闲且充电时做完整AOT编译,日常使用靠JIT临时加速,这样既保住了安装速度,也没有牺牲运行性能。

art虚拟机原理是什么?从dex2oat到混合编译

想真正理解ART的底层机制,核心先看dex2oat,这个名字是“dex to OAT”的意思,OAT文件是ART的可执行格式,本质上是包裹着机器码的ELF文件。

dex2oat的编译流水线大致如下:

  • 解析DEX文件里的类定义和方法字节码
  • 运行优化器做内联、常量折叠等优化
  • 生成对应指令集的机器码,放进.oat段
  • 保留一个紧凑的DEX副本供解释模式使用

整个链路里,优化器的决策直接影响最终性能,比如同样的循环体,开启内联后能减少函数调用开销,运行耗时下降幅度相当可观。

混合编译模式下的执行策略

从Android 7.0开始,ART内部有三套执行引擎在轮换使用:

  1. 解释器:最先启动,处理冷启动时的低频方法,不做任何编译
  2. JIT编译器:监测热点方法,达到阈值后编译并缓存到JIT代码缓存区
  3. AOT编译器:后台把频繁使用的方法完整编译成OAT机器码

这套机制很像一个学生先速读,发现常考知识点后精读,最后把笔记整理成一本小抄,三种模式之间的切换由Profile引导编译驱动,系统记录每次运行的采样数据,生成Profile文件,下次安装或更新时只编译高频方法。

art虚拟机垃圾回收机制详解:内存管理的底层逻辑

垃圾回收是ART最复杂的部分,相比Dalvik相对简单的回收器,ART引入了多个收集器,按内存压力按需切换。

ART的GC大体分三个级别:

  • Sticky GC:只回收上次GC后新分配的对象,暂停时间极短
  • Partial GC:回收堆中除一部分常驻区域外的空间,兼顾暂停时间和回收效率
  • Full GC:整堆扫描回收,暂停时间最长,通常在内存压力极大时触发

多数情况下,ART优先触发Sticky GC,尽量避免Full GC带来的长暂停,配合并发标记算法,部分GC阶段的暂停时间可以控制在毫秒量级。

并发标记与暂停时间的博弈

ART的并发标记采用读屏障技术,让GC线程和应用线程可以同时运行,这意味着标记阶段不会长时间冻结应用,只有最后的清理阶段需要短暂暂停。

业内专家指出,Android 8.0以后ART用并发复制GC(Concurrent Copying GC)替代了CMS,配合读屏障把暂停时间压缩得更低,从玩家场景看,玩原神这类大型游戏时如果掉帧明显,可以在Logcat里找“Background young concurrent copying GC freed”这类日志,频繁出现并伴随较长耗时,往往意味着应用在短时间内创建了大量对象。

art虚拟机内存管理:对象分配与空间布局

说完GC,再看对象从哪来,ART的Java堆分成多个区域,各有分工。

  • Main Space:常规对象分配区域,默认使用RosAlloc分配器
  • Large Object Space:专门放大尺寸数组对象,比如位图解码时产生的整块像素数组
  • Non-Moving Space:放置不可移动的对象,比如类对象和常量池

RosAlloc是ART专门优化的分配器,它把堆整理成多个尺寸接近的内存块,每次分配时根据对象大小匹配一个空闲块,这样做的好处是碎片少、分配快,代价是元数据占用稍大。

对象头非常关键,ART对象头里有一个32位的lock word,同时承担锁状态、GC标记和身份哈希码的存储,synchronized方法在ART里走轻量锁优化路径,锁竞争不激烈时通过原子CAS完成加锁,不会挂起线程。

从原理到实践:ART相关的性能排查方向

理解了底层机制,最终要落在解决实际问题上,开发者在线上遇到的ART性能瓶颈一般有这几个场景:

  • 冷启动慢:先确认Profile引导编译是否生效,检查/data/misc/profiles/cur下是否有对应包名的Profile文件
  • 内存碎片化:大量小对象频繁创建会让RosAlloc碎片增加,观察Full GC频率是否异常
  • 安装耗时过长:Gradle构建时开启android.experimental.useR8和android.builder.enableDexingArtifactTransform=true,把部分优化前置到构建阶段

实操时,先在Android Studio里打开Memory Profiler,看GC类型和分配速率,再用systrace抓取GC暂停期间的帧渲染信息,这个组合可以覆盖大多数ART性能排查需求。

ART用“预编译+混合模式+精细化GC”换来了Android运行时的整体流畅,理解它的工作原理等于拿到一张系统排障地图,这套内存与编译机制仍在向低暂停、高并发的方向继续演进。

art虚拟机原理是什么?常见疑问解答

Q:art虚拟机与dalvik区别具体在哪?

A:核心区别在编译时机和编译策略,Dalvik是运行时JIT编译,ART是安装时或空闲时AOT编译,把字节码预先变成机器码,Android 7.0后的ART同时兼容两种策略,用Profile引导选择最优执行路径。

Q:ART为什么比Dalvik省电?

A:省电来自执行效率,运行机器码比解释字节码占用更少的CPU周期,同时GC暂停缩短也减少了系统唤醒频率,据Google公开的技术分享,ART在这方面的收益来自编译器优化和多代GC配合,而不是单纯的运行时参数调整。

Q:root后修改ART参数会影响系统稳定性吗?

A:会,修改堆大小上限、GC并发线程数这类参数,短期可能看到跑分提升,但多数情况下会导致系统进程被频繁杀死或触发异常GC,ROM调试阶段可以尝试,生产环境均使用ART默认配置。

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