JIT: What Is Just-In-Time Compilation and How It Works

Author: IT Sectr Published: 2026-04-16 Reading time: 9 min

JIT (Just-In-Time) is a dynamic compilation technology that converts bytecode or intermediate program representation into machine instructions directly during execution. In Android, the JIT compiler first appeared in version 2.2 Froyo as part of the Dalvik virtual machine and accelerated application execution by 2–5 times. According to Google, 2024, the modern JIT in ART combines interpretation with profiled compilation of hot methods.

Key Takeaways

  • JIT — Just-In-Time compilation: converting code into machine code directly while the program is running.
  • In Dalvik, JIT compiled hot methods after exceeding the call threshold (~200 times).
  • JIT reduces installation time and takes less space than full AOT compilation.
  • The main drawback is warm-up delay: the first seconds the application runs slower.
  • In modern ART, JIT is used in a hybrid mode with background AOT optimization.

What is JIT Compilation?

Just-In-Time (JIT) is a compilation method in which source code or bytecode is converted into machine instructions not in advance (as with AOT), but at the moment of the first call to the corresponding section of the program. The term “Just-In-Time” means that compilation happens “just in time” — immediately before execution.

The concept of JIT has existed since the 1960s, but gained widespread adoption with the advent of the Java Virtual Machine in 1995. JIT allows combining the portability of bytecode (write once — run anywhere) with performance close to native code. In the Java HotSpot VM, the JIT compiler analyzes the executed code and compiles only the most critical sections, saving time and memory.

How It Works

The JIT compiler receives bytecode as input, interprets it, and simultaneously collects statistics. When a certain code section (method, loop) is called frequently enough, JIT decides to compile it. The compiled machine code is stored in a cache — on subsequent calls, the already compiled version is used. This provides acceleration without having to compile the entire program.

java
// Example: a method becomes hot after multiple calls
public class HotMethod {
    private int compute(int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += i * i;
        }
        return sum;
    }
}

// Calling 500 times in a loop — JIT will compile compute
for (int t = 0; t < 500; t++) {
    hot.compute(1000);
}

JIT in Android: Dalvik and ART

In Android, JIT compilation went through three phases of evolution. The first phase — Dalvik without JIT (Android 1.0–2.1): pure interpretation of DEX bytecode. The second phase — Dalvik with JIT (Android 2.2–4.4): the introduction of the JIT compiler, which accelerated applications by 2–5 times. The third phase — ART with hybrid JIT (Android 7.0+): the return of JIT in a new capacity.

JIT in Dalvik was implemented as a trace-based compiler. It analyzed not individual methods, but chains of instructions (traces) that are frequently executed sequentially. This allowed compiling entire execution paths, including multiple methods. This approach was effective for mobile processors with small instruction caches, as the compiled trace fit into the L1 cache.

JIT in Modern ART

Starting with Android 7.0 Nougat, ART uses method-based JIT — it compiles individual methods based on execution profiles. This JIT works significantly faster than Dalvik JIT: typical compilation time for one method is 0.5–1 ms compared to 3–5 ms in Dalvik. The compiled code is stored in a separate memory area (JIT code cache) rather than in the application heap, which reduces fragmentation.

ParameterDalvik JITART JIT
TypeTrace-basedMethod-based
Compilation Speed3–5 ms/method0.5–1 ms/method
Compilation Threshold~200 callsDynamic
Code CacheIn application heapJIT code cache
ProfilingInternalExternal .prof files

Hot Method Detection and Compilation Thresholds

The central mechanism of JIT is hot method detection. Each method call increments an internal counter. When the counter crosses the threshold, the method is marked as “hot” and sent for compilation. In Dalvik, the threshold was fixed (~200 calls). In ART, counters are configured dynamically depending on the device’s available resources.

The compilation process includes several phases. The first — bytecode analysis: JIT examines the instruction stream and builds a data-flow graph. The second — optimization: inlining of small methods, dead code elimination, constant folding. The third — code generation: converting the optimized graph into machine instructions for a specific CPU architecture (ARM, ARM64, x86).

java
// Demonstration of inlining — JIT will inline the method body
public int inlineExample() {
    return square(5);
}

private int square(int x) {
    return x * x;
} // JIT will replace the call with return 5 * 5;

OSR — On-Stack Replacement

A special JIT technique — On-Stack Replacement (OSR). If a method contains a long loop that doesn’t finish for hundreds of iterations, JIT can compile the loop “on the fly” and replace the interpreted version with the compiled one right during execution. OSR is especially effective for computational tasks: rendering, image processing, cryptography.

JIT vs AOT: Comparative Analysis

JIT and AOT are two compilation approaches with opposing trade-offs. JIT sacrifices first-launch speed for compact distribution size and adaptability. AOT sacrifices installation time and disk space for maximum performance from the first second. Neither approach is absolutely better — the choice depends on the scenario.

The key advantage of JIT is adaptive optimization. JIT can use profile information unavailable to AOT: exact object types, actual call frequency, real branching patterns. This allows applying aggressive optimizations impossible with static compilation. For example, JIT can devirtualize method calls if only one receiver type is encountered in practice.

CriterionJITAOT
Installation TimeInstantDepends on size
First LaunchSlower (warm-up)Fast
Disk SpaceMinimal+15–30%
AdaptabilityHighLow
CPU UsageSpikes during compilationStable

When to Choose JIT

JIT compilation is preferable when fast deployment and disk space savings are important. In the context of mobile development, JIT is ideal for applications that are updated frequently (A/B testing, hotfixes). JIT is also convenient during development, when code is rebuilt dozens of times a day — each second saved on compilation accelerates the feedback loop.

Advantages of JIT Compilation

JIT provides developers with a number of practical advantages. First — small APK size. With the JIT approach, only bytecode (DEX) is packaged in the APK, which takes 20–30% less space than compiled native code. For users with limited built-in storage, this is a significant advantage.

The second advantage is device adaptation. JIT compiles code taking into account the actual CPU architecture, RAM size, and current load. For example, on a device with 2 GB of RAM, JIT may compile less aggressively to save memory, while on a flagship with 12 GB, it can apply all possible optimizations. AOT compilation, on the other hand, fixes the decision at installation time.

Platform Independence

Bytecode remains platform-independent, which simplifies application distribution. One APK works on ARM, ARM64, and x86 devices, and JIT generates native code for each architecture. The AOT approach would require either including multiple native code variants in the APK (increasing size) or compiling a separate version for each architecture.

Disadvantages and Limitations of JIT

The main disadvantage of JIT is warm-up delay. The user experiences slowdowns in the first seconds of the application while JIT compiles hot methods. In games, this manifests as stuttering in the initial levels. In applications with animations — jerky first transitions between screens.

The second disadvantage — power consumption. The compilation process heavily loads the CPU, increasing power consumption by 10–20% during the warm-up period. On battery-powered devices, this reduces battery life. It is especially noticeable in scenarios with frequent application restarts (multitasking with limited memory, where the system unloads and reloads processes).

Cache Fragmentation

Another issue — JIT cache fragmentation. The compiled code is stored in a continuous memory area. When new classes are loaded and additional methods are compiled, the cache becomes fragmented, increasing memory management overhead. In Dalvik, this problem was solved by periodic cache clearing; in ART, the JIT cache is allocated separately from the heap and uses its own defragmentation strategy.

Hybrid Mode: Best of Both Worlds

The modern approach in ART — hybrid compilation, combining the strengths of JIT and AOT. During application installation, no compilation is performed — only bytecode verification (verify). This ensures fast installation and minimal space usage. The first launches run in interpretation mode with JIT compilation of hot methods — the user gets acceptable performance without long waiting times.

Simultaneously, a background profiler collects data about real usage. After 2–3 full application launches, the profile reaches sufficient completeness, and the system launches dex2oat to compile hot methods into native code. This operation is performed in the background when the device is not loaded (charging, screen off). After background AOT completes, the application achieves performance comparable to full AOT compilation.

bash
# Forced start of background compilation
adb shell cmd package compile -m speed-profile -f com.example.app

# View compilation status
adb shell cmd package dump-profiles com.example.app

Results of the Hybrid Approach

According to Google I/O 2017, hybrid compilation reduced application installation time by 30–50% compared to pure AOT. The disk space occupied on the system partition decreased by 20–30%. At the same time, performance after background compilation matches the level of full AOT. The only scenario where hybrid falls short of AOT is the first launch immediately after installation: the application runs in JIT mode and may be 10–15% slower.

Frequently Asked Questions

What is JIT compilation in simple terms?

JIT is a way to speed up a program where code is translated into machine language not in advance, but in parts while running. The most frequent sections are compiled and cached, while rare ones remain in their original form.

How is JIT different from AOT?

JIT compiles code during execution, saving space and speeding up installation. AOT compiles all code in advance — the application starts faster but requires more disk space and installation time.

Why was JIT removed from Android?

JIT wasn’t removed — it evolved. In Android 5.0, Dalvik with JIT was replaced by ART with pure AOT. In Android 7.0, JIT returned to ART as part of a hybrid system where it works together with background AOT compilation for optimal performance.

How does JIT affect power consumption?

JIT increases power consumption by 10–20% during the warm-up period due to CPU load. After hot method compilation completes, power consumption returns to normal levels. ART’s hybrid mode minimizes these spikes through background compilation.

Is JIT warm-up visible to the user?

Yes, in scenarios with intensive computations. The user may notice slowdowns in the first seconds of application operation or at the beginning of a game. In modern versions of Android (8.0+), the hybrid mode minimizes this effect thanks to profiled compilation.

Summary

  • JIT (Just-In-Time) is dynamic compilation that converts bytecode into machine instructions during execution.
  • In Android, JIT evolved: trace-based in Dalvik → full AOT → hybrid JIT+AOT in modern ART.
  • Hot methods are detected through call counters and compiled when the threshold is exceeded (~200 calls).
  • OSR (On-Stack Replacement) allows compiling long loops on the fly without interrupting execution.
  • Main advantages of JIT: small APK size, fast installation, and device adaptation.
  • Main disadvantages: warm-up delay, peak power consumption, and cache fragmentation.
  • ART hybrid mode (Android 7.0+) reduces installation time by 30–50% while maintaining high performance.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also