JVM Internals & Memory

Bytecode & Execution

Bytecode is a compact stack-machine instruction set: ~200 opcodes pushing and popping an operand stack per frame. javap -c disassembles it — the ground truth for "what does this Java actually compile to".
  • Stack machine: operands push/pop on the operand stack; locals live in numbered slots
  • Opcode families: loads/stores (aload_0), arithmetic (iadd), control (ifeq, goto), invocation, allocation
  • Five invokes: invokevirtual, invokeinterface, invokespecial, invokestatic, invokedynamic
  • invokedynamic (indy) powers lambdas, string concat, records' generated methods
  • The verifier proves type safety before execution — malformed bytecode never runs
  • String switch, boxing, string concat: all sugar — javap shows the truth
javap: reading the truth
int add(int a, int b) { return a + b; }

$ javap -c Adder
  int add(int, int);
    Code:
       0: iload_1        // push local slot 1 (a)
       1: iload_2        // push local slot 2 (b)
       2: iadd           // pop two ints, push sum
       3: ireturn        // return top of stack
// slot 0 is `this` for instance methods

The class file contains the constant pool (all symbolic references: names, types, string literals), method bytecode with per-method max-stack/max-locals, exception tables, and attributes (line numbers, generics signatures — how erasure coexists with reflection). Frames are fixed-size at compile time; there is no runtime stack "growth" per method.

Dispatch: invokestatic and invokespecial (constructors, private, super.) bind at link time; invokevirtual dispatches through the receiver's vtable; invokeinterface searches itables. invokedynamic defers the decision to a bootstrap method at first execution — the hook that lets Lambdas be allocated lazily by LambdaMetafactory, and lets string concatenation pick optimal strategies at runtime (JEP 280), all invisible at the source level.

Sugar exposed
String s = "n=" + n;          // javap: invokedynamic makeConcatWithConstants
Integer x = 5;                 // javap: invokestatic Integer.valueOf
for (String w : list) {...}    // javap: Iterator.hasNext/next loop
switch (color) { case "RED"... // javap: hashCode switch + equals confirm
Sources
  • Optimizing JavaCh. 9 — Code Execution on the JVM
  • Optimizing Cloud Native Java (2nd ed.)Ch. 6 — Code Execution on the JVM
  • Core Java, Volume I: Fundamentals (13th ed.)Ch. 11.6 — Bytecode Engineering