Cambridge 9618 · International A Level Computer Science · ~15 min read
Notes
Video
Slides
Quiz
Worksheet
Three Execution Approaches
When a programmer writes source code, there are three main approaches to turn it into running instructions. The intermediary code / bytecode approach sits between native compilation and pure interpretation:
1. Native Compilation
Source code → native machine code for a specific CPU
Runs at maximum speed — no runtime translation
Platform-specific — must recompile for each OS/CPU
Examples: C, C++, Go, Rust
2. Bytecode / Intermediary Code
Source code → bytecode → VM executes on any platform
Platform-independent — same bytecode, different VMs
Near-native speed with JIT compilation
Examples: Java (JVM), C# (.NET CLR), Python
3. Pure Interpretation
Source code translated and executed line by line
No intermediate representation
Slowest — full translation overhead every run
Examples: early BASIC, shell scripts
Execution pipelines
Native compilation (C/C++)
Source .c
→
Compiler (once)
→
Native .exe
→
CPU executes
Bytecode approach (Java)
Source .java
→
javac
→
Bytecode .class
→
JVM
→
CPU
Pure interpretation
Source code
→
Interpreter (every run)
→
CPU
Intermediary Code (Bytecode)
Bytecode (also called intermediary code or p-code) is an intermediate representation between source code and native machine code. It is designed to be:
Compact — smaller than source code, efficient to store and transfer
Platform-independent — not specific to any CPU architecture
Easy to execute by a software virtual machine
A lower-level representation than source code but still abstract — closer to machine code but not tied to one CPU
Java source → Bytecode example
// Java source int x = 3 + 5; System.out.println(x);
The JVM is the software virtual machine that executes Java bytecode. It provides a complete execution environment — abstracting away the underlying hardware and OS so the same .class files run anywhere.
JVM reads .class bytecode files and executes them
Each platform (Windows, macOS, Linux, Android) has its own JVM implementation
The JVM provides: bytecode execution, JIT compilation, memory management (garbage collection), and a security sandbox
"Write once, run anywhere" (WORA) — the key design principle
JIT Compilation vs Pure Interpretation
⚡ JIT Compilation
Identifies hot spots — frequently executed bytecode sections
Compiles hot bytecode to native machine code at runtime
Same bytecode runs on any platform with the VM installed — Windows, Mac, Linux, Android. No recompilation per platform.
🔒
Security Sandbox
The VM can check bytecode before execution, preventing certain attacks. Code runs in a controlled environment with restricted access to the system.
🗑️
Automatic Memory Management
Garbage collection frees memory automatically — no manual malloc/free needed (unlike C). Prevents memory leaks and dangling pointers.
⚡
Runtime Optimisation
JIT compilers can optimise based on actual runtime behaviour — e.g. optimising loops that actually run frequently, which static compilers can't know ahead of time.
Disadvantages of the Bytecode VM Approach
Startup overhead: the JVM/CLR must load and initialise before any code runs; JIT compilation takes time during the warmup phase
Memory overhead: the VM itself uses significant RAM — the JVM runtime can require hundreds of MB even for small programs
Performance ceiling: even with JIT, rarely matches hand-optimised native code for CPU-intensive work
Complexity: the VM layer adds complexity to debugging and profiling
🗑️ Garbage Collection
The JVM and CLR both include automatic garbage collection. When an object is no longer referenced by any variable, the garbage collector identifies it as unreachable and frees its memory. This happens automatically without the programmer needing to call free() (as in C). Benefits: prevents memory leaks, eliminates dangling pointer bugs. Drawback: GC pauses can cause brief latency spikes ("stop-the-world" pauses).
Cambridge 9618 exam tip: Understand the TWO uses of "virtual machine" in 9618: (1) hardware VM (3.3.2) — hypervisor, Type 1/Type 2, running full guest OS; (2) bytecode VM (this lesson) — JVM/CLR, executes intermediary code, enables portability. For bytecode VMs: source → bytecode (by compiler) → VM → (JIT) → native code. Key advantages: portability (write once, run anywhere), security sandbox, automatic garbage collection. Key disadvantage: startup overhead, memory overhead vs native. Know both JVM (Java → .class bytecode) and CLR (.NET → CIL). JIT = hot bytecode compiled to native at runtime, faster than interpretation.
⚠️ Common Mistakes
Confusing the JVM with the Java compiler — javac compiles .java to .class bytecode; the JVM RUNS the bytecode — they are different programs
Saying JIT compiles at startup — JIT compiles HOT SPOTS (frequently executed sections) identified DURING runtime, not the whole program before execution
Saying bytecode is machine code — bytecode is NOT native machine code; it cannot run directly on a CPU; it must be interpreted or JIT-compiled by the VM
Confusing the JVM with hardware VMs — a hardware VM (hypervisor) runs a complete guest OS; a bytecode VM (JVM) runs bytecode for a single application; they use different mechanisms
Forgetting garbage collection — automatic memory management is a key feature of VMs like JVM and CLR; it frees unreachable objects automatically
✅ Notes completed!
▶
Video coming soon
Click slide or press arrow keys to navigate
Worksheet — 3.4.2 VM for Intermediary Code
8 questions · Cambridge 9618 standard
Q1Describe what bytecode (intermediary code) is and how it differs from both source code and native machine code.[3]
✅ Mark scheme
Bytecode is an intermediate code representation between source code and native machine code [1]; unlike source code, bytecode is not human-readable and is closer to machine instructions — it has already been parsed and compiled from the source language [1]; unlike native machine code, bytecode is not specific to any CPU architecture — it cannot be executed directly by a CPU and must be processed by a virtual machine (JVM/CLR); it is platform-independent [1].
Q2Explain how the JVM enables a Java program to run on both Windows and Linux without recompilation.[3]
✅ Mark scheme
The Java compiler (javac) compiles Java source code (.java) into platform-independent bytecode (.class files) once [1]; both Windows and Linux have their own implementations of the JVM — the JVM on each platform reads the same .class bytecode files and translates them to native machine code for that specific platform [1]; because the bytecode is not tied to any CPU or OS, the same .class files run on any machine with a JVM installed — write once, run anywhere [1].
Q3Compare JIT compilation to pure interpretation of bytecode. Which gives better runtime performance and why?[4]
✅ Mark scheme
JIT compilation gives better runtime performance [1]; JIT identifies frequently-executed sections of bytecode (hot spots) and compiles them to native machine code at runtime — the compiled native code is cached and reused each time those sections execute [1]; pure interpretation must process each bytecode instruction through the interpreter loop every time it executes — including in tight loops where the same instructions execute millions of times; this adds substantial overhead [1]; with JIT, after the initial warmup compilation, the code runs at native speed because the CPU is executing compiled machine code, not going through an interpreter [1].
Q4State two advantages and one disadvantage of using a bytecode VM approach compared to compiling directly to native machine code.[3]
✅ Mark scheme
Advantages — any two from: portability — same bytecode runs on any platform with a compatible VM, no platform-specific recompilation [1]; security sandbox — the VM can validate bytecode before execution and restrict access to system resources [1]; automatic garbage collection — the VM manages memory automatically, preventing leaks and dangling pointers [1]; runtime optimisation — JIT can optimise based on actual execution patterns, which ahead-of-time compilers cannot do [1]; disadvantage: startup and memory overhead — the VM itself requires loading/initialising, JIT compilation takes time, and the runtime uses significant RAM compared to a lean native executable [1].
Q5What is the equivalent of the JVM for .NET programs? What intermediate code does it execute?[2]
✅ Mark scheme
The CLR — Common Language Runtime [1]; it executes CIL — Common Intermediate Language (also accepted: MSIL — Microsoft Intermediate Language) [1].
Q6A student says "bytecode virtual machines and hardware hypervisors are the same thing — both are virtual machines." Evaluate this claim.[3]
✅ Mark scheme
The student is partially correct — both are called virtual machines and both virtualise something [1]; however they are fundamentally different: a hardware hypervisor (Type 1/Type 2) virtualises a complete computer system — it allows a full guest operating system to run, managing virtual CPU, RAM, and I/O; used for running multiple OS instances on one physical machine [1]; a bytecode VM (JVM/CLR) virtualises an execution environment for a specific language runtime — it runs bytecode for a single application, providing portability across platforms; it does NOT run a complete OS [1]. The term "virtual machine" covers both concepts but they solve entirely different problems.
Q7Explain the role of the Java Virtual Machine (JVM) in executing Java programs. Describe how a Java source file becomes a running program, naming every intermediate step and artefact produced.[5]
✅ Mark scheme
Step 1: Java source code (.java) is compiled by the Java compiler (javac) [1]; Step 2: compiler produces bytecode stored in a .class file — platform-independent intermediate code [1]; Step 3: the JVM on the target machine loads the .class file and either interprets it or uses Just-In-Time (JIT) compilation to convert bytecode to native machine code [1]; JVM executes the machine code, managing memory (garbage collection), security, and platform abstraction [1]; the JVM must be installed on each target machine, but the same .class file runs unchanged on Windows, macOS, and Linux — "write once, run anywhere" [1].
Q8Explain what Just-In-Time (JIT) compilation is and how it differs from both ahead-of-time compilation and pure interpretation. State one advantage and one disadvantage of JIT compilation compared to traditional ahead-of-time compilation.[4]
✅ Mark scheme
JIT: compiles bytecode (or source) to native machine code at runtime, just before execution — not before the program is distributed [1]; differs from ahead-of-time: AOT compiles to machine code before distribution; JIT compiles during execution [1]; differs from pure interpretation: pure interpreters translate each instruction on every execution; JIT compiles hot code paths once and caches the machine code for reuse [1]; Advantage: JIT-compiled code runs near native speed and can optimise based on actual runtime data (e.g. branch prediction based on observed behaviour) [1]; Disadvantage: compilation overhead occurs at startup / first execution — JIT-compiled programs have a warm-up delay before reaching full performance [1]. Award max 4.
Topic Quiz
Question 1 of 10
You scored
out of 10
Card 1 of 8
Click to reveal definition
🎉
All cards reviewed!
Term
Definition
🎯
Mini Test — 3.4.2 VM for Intermediary Code
10 questions · 10 marks · 10 minutes
⏱ 10:00
Section A — Multiple Choice [5 marks]
Q1What is bytecode?
Q2Which tool converts Java source code into bytecode?
Q3What does JIT stand for in the context of the JVM?
Q4What is CIL (Common Intermediate Language)?
Q5What is a "hot spot" in the context of JIT compilation?
Section B — Short Answer [5 marks]
Q6State the full execution pipeline for a Java program, from source code to the CPU running instructions.
Mark schemeJava source code (.java) → compiled by javac → Java bytecode (.class files) → loaded by JVM → JIT compiler compiles hot bytecode to native machine code → CPU executes native instructions [Full pipeline with all stages = 2 marks; 3 or more stages correctly ordered = 1 mark].
Q7Give two benefits of using bytecode VMs over compiling directly to native code.
Mark schemeAny two from: portability — same bytecode runs on any platform with a compatible VM (write once, run anywhere) [1]; security sandbox — the VM validates bytecode and restricts system access [1]; automatic garbage collection — VM manages memory, preventing leaks [1]; runtime JIT optimisation based on actual execution patterns [1].
Q8Explain what garbage collection does in the context of the JVM.
Mark schemeGarbage collection automatically frees memory that is no longer being referenced/used by the program [1]; when an object has no remaining references (no variable points to it), the garbage collector identifies it as unreachable and reclaims its memory — the programmer does not need to manually free memory (unlike C with malloc/free) [1].
Q9State one disadvantage of the bytecode VM approach compared to native compilation.
Mark schemeAny one of: startup overhead — JVM/CLR must load and initialise; JIT compilation takes time during warmup before peak performance is reached [1]; memory overhead — the VM runtime itself uses significant RAM even for small programs [1]; performance ceiling — even with JIT, native code can be hand-optimised to run faster for CPU-intensive tasks [1].
Q10How does the CLR differ from the JVM? Give one similarity and one difference.
Mark schemeSimilarity: both are virtual machines that execute intermediary bytecode (JVM: Java bytecode; CLR: CIL), both use JIT compilation to improve performance, both provide automatic garbage collection [1]; difference: the JVM primarily runs Java (and JVM-compatible languages like Kotlin/Scala); the CLR runs .NET languages (C#, VB.NET, F#); they execute different bytecode formats that are not interchangeable [1].