JVM Internals
Resources
- https://blog.jamesdbloom.com/JVMInternals.html
- https://www.artima.com/insidejvm/ed2/jvm2.html
- https://wiki.openjdk.java.net/display/HotSpot/JavaControlStack
Overview
Key Parts
Thread
- JVM allows application to have multiple threads running concurrently
- Directly map to native OS Threads
- Java thread setup contains
- See
- Thread-Local Storage
- Allocation Buffers
- Synchronisation Objects
- Stacks
- Program Counter
- Then native thread is established
- Reclaimed once Java thread terminates
- Thread scheduling managed by OS
- Invoked with
run()
- When
run()
returns:- Exceptions are handled
- Native thread confirms if whole JVM needs to be terminate as a result of thread termination (i.e. last non-daemon thread)
- When
- On thread termination, all resources for both native and java thread are freed
Secondary Threads
Even without threading, a JVM program will run multiple system threads simultaneously to support the main thread. Mainly:
- VM Thread
- Waits for operations that need JVM to be in safe state (won’t modify the heap)
- Particularly:
- Stop-the-world Garbage Collection
- Thread stack dumps
- Thread suspension
- Biased locking revocation
- Periodic Task Thread
- Responsible for timer events for periodic operations
- GC Threads
- For other kinds of Garbage Collection operations
- Compiler Threads
- Compile byte code to native at runtime
- Signal Dispatcher Thread
- Handles inbound Signals to JVM process (presumably OS)
Per-Thread
Program Counter (PC)
- Address of current instruction (same as Assembly program counter)
- If current method is native, PC is undefined
- Each CPU has a PC
- Typically incremented after each instruction, holding address of next instruction
- Will point to a memory address in the Method Area
Stack
- JVM uses a Last In First Out Stack Frame structure
- Currently executing method will be top of the stack
- Method calls will push new stack frame to top of stack, and popped on return
- Stack is not directly manipulated
- NOTE: Frame Objects may be allocated in the Heap, and memory may not be contiguous
Native Stack
- For native methods (if supported by the JVM), typically creates per-thread native stack
- Depends on linkage mode:
- E.g. C-Linkage Model for Java Native Invocation will be a C stack and work like a C stack (e.g. argument order and return values)
- A native method can (depending on JVM) invoke Java method.
- Such invocation exits the Native Stack and creates call frame on Java Stack
Stack Restrictions
- Stack can be dynamic or fixed size
- If a thread requires a larger stack than allowed, will throw a
StackOverflowError
- If a thread requires new frame and there’s insufficient memory, will throw
OutOfMemoryError
Frame
- See: https://www.artima.com/insidejvm/ed2/jvm8.html
- Frame pushed to stack on invocation
- Popped on return or for uncaught exception
- See Exception Handling
Frame Layout
Each Frame contains
- Local Variable Array
- Return Value
- Operand Stack
- Frame Data
- Ref to runtime constant pool for class of current method
LVA and Operand Stack size measured in words, are determined at compile time, and included in class file data for each method.