/ˌdʒeɪ-aɪ-ˈtiː/
n. “Compiling code at the exact moment it becomes useful.”
JIT, short for just-in-time compilation, is a runtime compilation strategy where source code or intermediate bytecode is translated into machine code while the program is running. Instead of compiling everything up front, the system waits, observes what code is actually being executed, and then optimizes those hot paths on the fly.
The philosophy behind JIT is pragmatic laziness… don’t optimize what you might never use. By compiling only the portions of code that are actively exercised, a JIT compiler can apply aggressive, context-aware optimizations based on real runtime behavior such as loop frequency, branch prediction, and actual data types.
JIT compilation is a cornerstone of many modern runtimes, including:
- the Java Virtual Machine (JVM)
- JavaScript engines like V8 and SpiderMonkey
- .NET’s Common Language Runtime (CLR)
A classic example is JavaScript in the browser. When a script loads, it may first be interpreted or lightly compiled. As certain functions run repeatedly, the JIT compiler steps in, recompiling those sections into highly optimized machine code tailored to the user’s actual execution patterns.
Compared to AOT (ahead-of-time compilation), JIT offers greater flexibility. Dynamic features like reflection, runtime code generation, and polymorphic behavior thrive under JIT. The cost is additional runtime overhead, including warm-up time and increased memory usage.
The tradeoffs can be summarized cleanly:
- JIT: slower startup, faster peak performance, highly adaptive
- AOT: faster startup, predictable performance, less dynamic
Modern systems often blend the two approaches. For example, a runtime might use AOT compilation for baseline execution and layer JIT optimizations on top as usage patterns stabilize. This hybrid model attempts to capture the best of both worlds.
At its core, JIT is about opportunism. It waits, watches, and then strikes… turning lived execution into insight, and insight into speed.