Understanding the Java Virtual Machine
The JVM enables the principal of "write once, run anywhere" by acting as an intermediary between compiled Java bytecode and the underlying hardware.
JVM vs Physical Machines
In this analogy:
- Input devices correspond to Class files
- Output devices correspond to CPU instruction sets
- The JVM represents memory, control units, and arithmetic components
Popular JVM Implementations
The most widely used implementation today is HotSpot. You can check your version using java -version.
- Oracle: HotSpot, JRockit
- IBM: J9 VM
- Alibaba: TaobaoVM
- Azul: Zing
JDK, JRE, and JVM Relationship
The JVM's primary responsibilities include:
- Translating Class files into platform-specific CPU instructions
- Enabling cross-platform compatibility
Class File Format
Source Code Example
Various languages can compile to Class files, including Java, Kotlin, and Groovy:
public class User {
private Integer age;
private String name = "snail";
private Double salary = 100.0;
private static String address;
public void say() {
System.out.println("snail Say...");
}
public static Integer calculate(Integer operand1, Integer operand2) {
operand1 = 3;
Integer sum = operand1 + operand2;
return sum;
}
public static void main(String[] args) {
System.out.println(calculate(1, 2));
}
}
Compilation Process
Compile using: javac User.java to generate User.class
Class File Structure
Class files consist of 8-bit binary streams arranged sequentially without separators. Multi-byte data uses big-endian format.
Two fundamental data types exist:
- Unsigned numbers (primitive types)
- Tables (reference types)
Viewing Bytecode
Use the JDK's javap tool: javap -v User.class > User.txt
For binary inspection, Notepad++ with HEX Editor plugin displays raw bytes.
Class File Layout
ClassFile {
u4 magic_number; // Magic identifier (0xCAFEBABE)
u2 minor_version; // Minor version number
u2 major_version; // Major version number
u2 constant_pool_size; // Number of constant pool entries + 1
cp_info constant_pool[constant_pool_size-1];
u2 access_flags; // Class access modifiers
u2 this_class_index; // Index to current class
u2 super_class_index; // Index to parent class
u2 interfaces_count; // Number of implemented interfaces
u2 interfaces[interfaces_count];
u2 fields_count; // Number of fields
field_info fields[fields_count];
u2 methods_count; // Number of methods
method_info methods[methods_count];
u2 attributes_count; // Number of attributes
attribute_info attributes[attributes_count];
}
Structure Analysis
- Magic Number (cafebabe): Identifies the file as a valid Class file
- Version Numbers (0000 + 0034): Hex 34 = decimal 52, indicating JDK 8
- Constant Pool Size (0043): Hex 43 = decimal 67, meaning 66 constant entries
Constant Pool Structure
cp_info {
u1 tag;
u1 info[];
}
Constant Types
| Constant Type | Tag Value |
|---|---|
CONSTANT_Class |
7 |
CONSTANT_Fieldref |
9 |
CONSTANT_Methodref |
10 |
CONSTANT_InterfaceMethodref |
11 |
CONSTANT_String |
8 |
CONSTANT_Integer |
3 |
CONSTANT_Float |
4 |
CONSTANT_Long |
5 |
CONSTANT_Double |
6 |
CONSTANT_NameAndType |
12 |
CONSTANT_Utf8 |
1 |
CONSTANT_MethodHandle |
15 |
CONSTANT_MethodType |
16 |
CONSTANT_InvokeDynamic |
18 |
Constant Analysis Examples
First Constant (0a = 10): Method reference
CONSTANT_Methodref_info {
u1 tag;
u2 class_reference; // Index to containing class
u2 name_type_reference; // Index to name and type descriptor
}
Result: #1 = Methodref #16.#35 // java/lang/Object."<init>":()V
Second Constant (08 = 8): String reference
CONSTANT_String_info {
u1 tag;
u2 string_reference; // Index to UTF-8 string
}
Results:
#1 = Methodref #16.#35 // java/lang/Object."<init>":()V
#2 = String #36 // snail
Disassembly
The javap command disassembles Class files. Conceptually, the JVM acts as an operating system for Class files, which serve as its machine langauge.