JVM, Dalvik, ART
Java Virtual Machine (JVM)
I can use javac
to compile my Java programs (*.java) to Java bytecode (*.class), so that I can run my Java application on Java Runtime Environment (JRE).
JRE includes JVM, Java API library and other components. JVM is an abstract computing machine, it is ported to different platforms to provide hardware- and operating system-independence. A Just-In-Time (JIT) compiler can translate Java bytecode into native machine code.
Dalvik
Dalvik is the virtual machine for Android platform. Android SDK tools has dx
tool, it can compile Android programs into Dalvik Executable files (.dex). It also has dexopt tool
that can optimize DEX to ODEX files, hen JIT compile them to machine code.
Android Runtime (ART)
ART use ahead-of-time (AOT) compilation to improve app performance. At install time, ART uses dex2oat tool
to compile DEX files to Executable and Linkable Format (ELF) files.
Virtual Machine | JVM | Dalvik VM | ART |
---|---|---|---|
type of computer | stack-based | register-based | register-based |
executable file format | Java bytecode | DEX | DEX |
compiler | javac | dx | dx |
N/A | ODEX | N/A | |
machine code | machine code | ELF | |
compilation | JIT | JIT | AOT |
Android 5.0 Lollipop |
64K reference limit
Total number of references that can be invoked by the code within a single Dalvik Executable (DEX) bytecode file is 65,536 (64 X 1024). It ncluds Android framework methods, library methods, and methods in my own code.
trouble writing output:
Too many field references: 131000; max is 65536.
You may try using --multi-dex option.
The best way to solve this problem is enable code shrinking to run ProGuard for release builds.
I also can setting Gradle to allow my app to build and read multiple DEX files for version prior to Android 5.0 (API level 21).
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 26
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
At install time, ART compile DEX files into a single.oat
file, so it does not need the multidex
support library. A multidex configuration takes longer time to build application. I can use productFlavors
to create two build variants, so that I can reduce cost in development builds.
android {
defaultConfig {
...
multiDexEnabled true
}
productFlavors {
dev {
// Enable pre-dexing to produce an APK that can be tested on
// Android 5.0+ without the time-consuming DEX build processes.
minSdkVersion 21
}
prod {
// The actual minSdkVersion for the production version.
minSdkVersion 14
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}