Server-Side Java JVM ClassFormat
Class File Structure
-
magic
- CAFEBABE
-
minor version
-
major version
-
constant_pool_count
-
constant_pool
-
1 CONSTANT_Utf8_info
- 1 byte
- identifier
-
length
-
bytes
- 1 byte
-
3 CONSTANT_Integer_info
- 4 bytes
- Big-Endian (high-order byte first)
- int
- 4 bytes
-
4 CONSTANT_Float_info
- 4 bytes
- Big-Endian (high-order byte first)
- float
- 4 bytes
-
5 CONSTANT_Long_info
- 8 bytes
- Big-Endian (high-order byte first)
- long
- 8 bytes
-
6 CONSTANT_Double_info
- 8 bytes
- Big-Endian (high-order byte first)
- double
- 8 bytes
-
7 CONSTANT_Class_info
- 2 bytes
- index to the entry for the class's fully qualified name
- 2 bytes
-
8 CONSTANT_String_info
- 2 bytes
- index to the string literal entry
- 2 bytes
-
9 CONSTANT_Fieldref_info
- 2 bytes
- index to the descriptor of the class or interface that declares the field
- an index into CONSTANT_Class_info
- 2 bytes
- index to the field descriptor
- an index into CONSTANT_NameAndType_info
- 2 bytes
-
10 CONSTANT_Methodref_info
- 2 bytes
- index to the descriptor of the class or interface that declares the method
- an index into CONSTANT_Class_info
- 2 bytes
- index to the field descriptor
- an index into CONSTANT_NameAndType_info
- 2 bytes
-
11 CONSTANT_InterfaceMethodref_info
- 2 bytes
- index to the descriptor of the class or interface that declares the method
- an index into CONSTANT_Class_info
- 2 bytes
- index to the field descriptor
- an index into CONSTANT_NameAndType_info
- 2 bytes
-
12 CONSTANT_NameAndType_info
- 2 bytes
- index to the constant pool entry for the field or method name
- 2 bytes
- index to the constant pool entry for the field or method descriptor
- 2 bytes
-
15 CONSTANT_MethodHandle_info
- 1 byte
- a reference_kind value between 1 and 9
- determines the kind of method handle
- the method handle kind characterizes its bytecode behavior
- 1 byte
-
16 CONSTANT_MethodType_info
- 2 bytes
- descriptor_index
- index to a CONSTANT_Utf8_info structure representing the method descriptor
- 2 bytes
-
18 CONSTANT_InvokeDynamic_info
- 2 bytes
- bootstrap_method_attr_index
- a valid index into the bootstrap_methods[] array of this Class file's bootstrap method table
- 2 bytes
- index to a CONSTANT_NameAndType_info representing the method name and method descriptor
- 2 bytes
-
-
access_flags
- ACC_PUBLIC 0x0001 whether public
- ACC_FINAL 0x0010 whether final
- ACC_SUPER 0x0020 must be true
- ACC_INTERFACE 0x0200 whether an interface
- ACC_ABSTRACT 0x1000 interface or abstract class
- ACC_SYNTHETIC 0x1000 generated automatically by the compiler
- ACC_ANNOTATION 0x2000
- ACC_ENUM 0x4000
-
this_class
- current class
-
super_class
- superclass
-
interface_count
-
interfaces
-
filds_count
-
fields
-
methods_count
-
method_info
-
attribute_count
-
attribute
Class Loading Process
-
load
- Link: static variables are assigned default values
- Verification
-
Preparation
- Resolution
- symbolic references are resolved into direct references
- symbols in the constant pool are resolved into direct memory references such as pointers or offsets
- Initializing
- run the class initialization code
The Process of Creating an Object with new
- allocate memory
- assign default values
- constructor
- set initial values
ClassLoader Hierarchy
-
Top-down: performs the actual lookup and loading (child direction)
-
Bottom-up: checks whether the class has already been loaded (parent direction)
-
Loading hierarchy (from the Launcher source)
- Bootstrap
- loads core classes such as lib/rt.jar and charset.jar: implemented in C++
- sun.boot.class.path
- Extension
- loads extension jars, jre/lib/ext/*.jar
- or as set by -Djava.ext.dirs
- java.ext.dirs
- App
- loads what the classpath specifies
- java.class.path
- Custom ClassLoader
- custom ClassLoader
- Bootstrap
-
Loading mechanism
-
Parent Delegation
- Why parent delegation?
- Primary: security
- Secondary: resource savings
-
Java Concurrency
-
Java concurrency memory model
- Java thread -- working memory -- Save and Load operations <===> main memory
- Java thread -- working memory -- Save and Load operations <===> main memory
-
volatile
- Bytecode level
- ACC_VOLATILE
- JVM level: memory barriers wrap every read and write of volatile memory areas
- Write
- StoreStoreBarrier
- write operation
- StoreLoadBarrier
- Read
- LoadLoadBarrier
- read operation
- LoadStoreBarrier
- Write
- OS and hardware level
- hsdis-HotSpot Dis Assembler
- implemented via the lock instruction on Windows
- hsdis-HotSpot Dis Assembler
- Bytecode level
-
synchronized
- Bytecode level
- ACC_SYNCHRONIZED
- monitorenter
- monitorexit
- JVM level
- C/C++ calls the synchronization mechanisms provided by the OS
- OS and hardware level
- X86: lock comxchg xxx
- Bytecode level
JVM Reordering Rules
-
happens-before principle
- JLS17.4.5
-
as if serial
Object Memory Layout
-
What is the process of creating an object?
- class loading
- class linking()
- class initializing
- allocate memory for the object
- assign default values to member variables
- invoke the constructor
- assign initial values to member variables in order
- execute the constructor statements
-
How are objects laid out in memory?
- VM configuration
- Ordinary object
- object header markword 8
- ClassPointer
- Instance data
- Reference types: 4 bytes with -XX:+UseCompressedOops, 8 bytes without
- ordinary object pointers
- Reference types: 4 bytes with -XX:+UseCompressedOops, 8 bytes without
- Padding for alignment to a multiple of 8
- Array object
- object header markword 8
- ClassPointer
- -XX:+UseCompressedOops enabled: 4 bytes; disabled: 8 bytes
- Array length: 4 bytes
- Array data
- alignment to a multiple of 8
-
What exactly does the object header include?
- Obtained via the JavaAgent mechanism
- Instrumentation
- getObjectSize
- Instrumentation
- markword
- unlocked state
- lightweight lock
- heavyweight lock
- GC mark
- biased lock
- Obtained via the JavaAgent mechanism
-
How are objects located?
- Reference
- Handle pool
- Indirect pointer: better for GC
- Object
- Class
- Indirect pointer: better for GC
- Direct pointer: better for execution
- Object
-
How are objects allocated?
- GC-related topics
-
Example of object size
- How many bytes does a new Object() take?
- 16 bytes
- object header 8 bytes
- ClassPointer 4 bytes
- 16 bytes
- How many bytes does a new Object() take?
Rules for Hotspot Enabling Compressed Oops
- Below 4G, compression is simply disabled
- 4G-32G, compressed ClassPointers/Oops enabled by default
- 32G and up, compression is ineffective; 64-bit is used
JVM Runtime Data Area and JVM Instructions
- Data Area
-
Program Counter
- stores the current execution position
- the VM runs much like a while loop
-
JVM stacks
- Frame: stack frame
- Local Variable Table
- Operated Stacks
- Dynamic Linking
- Return Address
-
one method corresponds to one stack frame
- Frame: stack frame
-
Heap
-
Native Method stacks
- C/C++
- JNI
-
Direct Memory
- NIO, zero copy
- kernel memory the JVM can access directly
-
Method Area
- run-time constant pool
- Content
- Perm Space(< 1.8)
- string constants live here
- not cleaned up by Full GC
- size fixed at startup and cannot change
- Meta Space(>=1.8)
- string constants live in the heap
- can be cleaned up by Full GC
- if unset, the maximum is physical memory
- Perm Space(< 1.8)
-
JVM Instruction Set
- store
- load
- pop
- mul
- sub
- add
- invoke
- invokestatic
-
invokevirtual
- invokeinterface
- invokespecial
- can be located directly, no polymorphic dispatch needed
- private methods
- constructors
- can be located directly, no polymorphic dispatch needed
- invokedynamic: the hardest
- lambda expressions
- reflection
- other dynamic languages: scala, kotlin
- CGLib ASM
- dynamically generated classes
Garbage Collector GC turning
-
Familiar with common GC algorithms and mainstream garbage collectors, with hands-on JVM tuning experience
-
Garbage
- objects with no references pointing to them
- root searching
- GC roots
- thread stack variables
- static variables
- constant pool
- JNI pointers
- GC roots
- GC Algorithms
- Mark-Sweep
- two passes
- Copying
- one pass
- Mark-Compact
- two passes
- Mark-Sweep
-
Logical heap partitioning (not suitable for non-generational garbage collectors)
- ⚠️
- All GCs except Epsilon, ZGC and Shenandoah use a logical generational model
- G1 is generational logically but not physically
- the others are generational both logically and physically
- Young generation: MinorGC/YGC
- eden: 8
- survivor: 1
- survivor: 1
- Copying
- when the copying age exceeds the limit, objects move to the old generation. Configured via -XX:MaxTenuringThreshold
-
Old generation: MajorGC/FullGC
- ⚠️
-
Memory in detail
- Stack allocation
- small thread-private objects
- no escape
- supports scalar replacement
- no tuning needed
- Thread-local allocation buffer (TLAB)
- occupies Eden, 1% by default
- with multiple threads, space is allocated without contending for Eden, improving efficiency
- small objects
- no tuning needed
- Old generation
- survived more YGCs than the count set by XX:MaxTenuringThreshold
- Parallel Scavenge 15
- CMS 6
- G1 15
- Dynamic age
- s1->s2 exceeds a cumulative 50%
- move the oldest into Old
- if survivor space runs out during YGC, the space guarantee promotes objects straight to the old generation
- survived more YGCs than the count set by XX:MaxTenuringThreshold
- Stack allocation
-
Common garbage collectors
-
Single-threaded
- Serial
- threads stop at safepoints,
- most efficient on a single CPU
- the default collector in the VM's Client mode
- rarely used
-
Serial Old
- Serial
-
Multi-threaded
- Parallel Scavenge(PS) + Parallel Old(PO)
- throughput first
- ParNew+CMS
- CMS:
- enables concurrent collection
- CMS has quite a few problems
- memory fragmentation
- floating garbage
-
Response-time first
- CMS:
- Parallel Scavenge(PS) + Parallel Old(PO)
-
ZGC
-
G1
-
-
Algorithm for the Remark phase
- tri-color marking algorithm
- white, gray, black
- during concurrent marking
- tri-color marking algorithm
JVM Tuning
- -XX:+UseSerialGC
- Serial New + Serial Old
- small programs
- not the default; Hotspot automatically selects a collector based on the machine, configuration and JDK version
- -XX:+UseParNewGC
- ParNew + SerialOld
- rarely used
- -XX:UserConcMarkSweepGC
- ParNew + CMS + Serial Old
- -XX:UseParallelGC
- Parallel Scavenge + Parallel Old
- -XX:UseParallelOldGC
- Parallel Scavenge + Parallel Old
- -XX:UseG1GC
- G1
- Linux defaults
- Linux 1.8
- 1.8.0_181 default Copy MarkCompact
- 1.8.0_222 default PS + PO