ART虚拟机是Android 5.0之后默认的运行时环境,核心价值是用AOT预编译把应用启动和响应速度大幅拉高,性能优化关键点围绕编译策略、垃圾回收与内存管理展开。 下面我把底层原理和实操优化一起讲清楚。
ART虚拟机原理详解:AOT预编译和JIT即时编译是怎么配合的?
很多朋友问我,ART虚拟机到底是个啥?说白了,它就是Android的“翻译官”,负责把Java/Kotlin字节码变成设备能直接跑的机器码,但它和前辈Dalvik最大的不同,在于干活时机不一样。
ART虚拟机是什么:一个“预编译管家”
在旧时代,Dalvik虚拟机采用JIT即时编译,用户每次打开App都要现场翻译,所以启动慢、卡顿多,ART像个体贴的管家,在App安装时就用dex2oat把dex字节码先预编译成机器码,等你要开App时直接执行,少走很多弯路。
从Android 5.0开始,ART正式取代Dalvik成为默认运行时,后来Google发现全量预编译太占空间,在Android 7.0又引入了“JIT + Profile”混合模式,现在的ART已经是三管齐下:
- 安装时:快速编译关键代码,保证基本启动速度。
- 运行时:JIT记录热点方法,动态优化。
- 空闲充电时:根据使用频率做深度AOT编译,让常用App越用越顺。
dex2oat到底干了什么活
dex2oat是ART底层最核心的进程,它把classes.dex翻译成.oat文件,这个文件本质上是ELF格式的可执行镜像,包含本地机器码和元数据,同时还会生成.art文件,用于预加载系统类和字符串,减少冷启动开销。
想查看某个App的编译状态,可以执行:
adb shell dumpsys package dexopt
输出里会列出每个应用的dexopt状态、编译路径、编译模式等信息,一眼就能看出系统对它做了什么优化。
业内专家指出,ART的编译策略本质上是用安装时和闲置时的算力,换取运行时的响应速度,这句话算得上整个机制的“题眼”。
ART虚拟机性能优化关键点:编译模式、垃圾回收与内存调优
性能优化不是玄学,ART就三个抓手:编译、GC、内存。
编译模式怎么选:speed、balanced 还是 space?
ART的编译模式直接决定App的流畅度和ROM占用,常见的有这些:
- speed:全量AOT编译,启动和响应最快,但安装慢、占空间大。
- balanced:在速度和空间之间取平衡,适合大多数普通App。
- space:以最小存储占用为目标,适合64GB以内的小容量设备。
- verify:只做验证不编译,主要用于系统异常排查。
- quicken:轻量优化,编译速度快,但性能提升有限。
- speed-profile:根据用户实际使用记录编译“热方法”,兼顾速度和续航,是Android 10之后的主流推荐。
想确认当前设备默认用哪种模式,可以跑:
adb shell getprop | grep dexopt
结果里通常能看到类似pm.dexopt.install=speed-profile的配置,如果某个App总是卡,你也可以手动触发完整编译:
adb shell cmd package compile -m speed -f com.example.app
注意,全量编译后App占用的存储空间会明显增加,在小ROM手机上要谨慎使用。
垃圾回收:避免卡顿的隐藏开关
ART和Dalvik比,GC进步最大的地方是默认并发回收,在Android 8.0之后又加入了新一代分代GC机制,垃圾回收暂停时间大幅缩短,多数情况下都在极短可感知范围内。
但GC再强也怕“内存抖动”,如果App在短时间内频繁创建和释放对象,GC就会连续触发,卡顿、掉帧随之而来,实操建议包括这些:
- 在循环体里复用对象,减少临时变量。
- 用
SparseArray替代HashMap,避免自动装箱带来的额外内存。 - 不要在
onDraw里new对象,那是主线程卡顿的重灾区。 - 用
Android Studio Profiler抓Memory曲线,观察GC活动频率。
命令行层面,可以过滤查看GC日志:
adb logcat -s ART GC
如果看到WaitForGcToComplete或ConcurrentGC频繁出现,说明内存压力已经不小了。
内存管理和“大对象”陷阱
ART比Dalvik更擅长分配对象,但这也意味着你要更自律,典型问题就是Bitmap过大导致OOM,特别是在图片密集型应用里,针对这类场景,优化思路有:
- 用
BitmapFactory.Options做采样压缩,避免原图直接进内存。 - 使用
android:largeHeap="true"要慎重,它拉高了堆上限,却会增加GC压力。 - 用协程把后台图片解码挪出主线程,减少主线程内存峰值。
对于低内存设备,可以限制后台进程数量,让系统更专注于当前活跃App,这也是变相帮着ART“腾地方”。
ART虚拟机与Dalvik区别对比:谁更值得选?
在Android 4.4时代,很多老玩家纠结“art虚拟机和dalvik哪个好”,答案很明确:ART让Android从“能用”变成了“流畅”。
表格对比:一文看懂区别
| 对比维度 | Dalvik虚拟机 | ART虚拟机 |
|---|---|---|
| 执行方式 | JIT逐行解释 | AOT预编译为主,JIT辅助 |
| 安装耗时 | 短,无需预编译 | 安装阶段编译,耗时稍长 |
| 启动速度 | 每次启动都要解释,较慢 | 直接执行机器码,启动快 |
| 内存占用 | 较低但GC频繁 | 有一定额外开销,但GC更稳 |
| GC暂停 | 频繁且时间较长 | 并发回收,暂停时间大幅缩短 |
| 系统版本 | Android 4.4及早期 | Android 5.0及之后 |
为什么ART成了唯一选择
行业共识认为,ART的收益远大于成本,安装时多等几十秒,换来的是整个生命周期内更稳定的流畅度,对大型游戏、复杂动画和密集型社交App来说,ART是必不可少的底层支撑。
如果你还在设备上手动切换ART和Dalvik,那基本是Android 4.4的往事,现在只要是Android 5.0以上的系统,ART一直在后台默默干活,你要做的其实是调整它的干活方式。
说到根上,ART虚拟机不是玄学,它的性能优化就藏在那几个系统参数和开发习惯里,要提升App流畅度,优先检查编译模式、GC压力和内存峰值,这三个点解决之后,体验基本不会差。
ART虚拟机常见问题:性能优化与底层原理答疑
这里集中回答几个搜索热度不低的问题。
ART虚拟机会增加APK体积吗?
不会直接改变APK体积,但安装后占用的存储空间会明显增加,因为预编译生成的.oat文件通常比.dex大不少,部分高优化模式还会生成额外的Profile文件,如果你ROM空间紧张,可以把不常用App改回space模式,或直接使用Android自带的“卸载未使用应用”功能。
手动优化ART能提升游戏帧率吗?
有一定帮助,尤其对游戏场景,使用speed-profile或speed模式编译游戏进程,能减少运行时编译开销,帧率稳定性会更好,操作方式就是前面提到的cmd package compile命令,但要注意,如果游戏瓶颈在GPU和CPU本身,ART的优化空间就有限,此时应该优先降低画质和特效。
为什么手机息屏充电时反而变慢?
很多时候是系统在做后台编译优化,Android会在设备充电且屏幕熄灭的时段,对最近使用过的App进行预编译加速,这是正常现象,说明ART正在利用空闲时间帮你优化接下来的打开速度,等这轮加速跑完,手机又会恢复正常。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/773394.html


