Server-Side Java JVM ClassFormat

2022-03-20

Class File Structure

  • magic

    • CAFEBABE
  • minor version

  • major version

  • constant_pool_count

  • constant_pool

    • 1 CONSTANT_Utf8_info

      • 1 byte
        • identifier
      • length

      • bytes

    • 3 CONSTANT_Integer_info

      • 4 bytes
        • Big-Endian (high-order byte first)
        • int
    • 4 CONSTANT_Float_info

      • 4 bytes
        • Big-Endian (high-order byte first)
        • float
    • 5 CONSTANT_Long_info

      • 8 bytes
        • Big-Endian (high-order byte first)
        • long
    • 6 CONSTANT_Double_info

      • 8 bytes
        • Big-Endian (high-order byte first)
        • double
    • 7 CONSTANT_Class_info

      • 2 bytes
        • index to the entry for the class's fully qualified name
    • 8 CONSTANT_String_info

      • 2 bytes
        • index to the string literal entry
    • 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
    • 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
    • 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
    • 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
    • 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
    • 16 CONSTANT_MethodType_info

      • 2 bytes
        • descriptor_index
        • index to a CONSTANT_Utf8_info structure representing the method descriptor
    • 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
  • 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
    1. Verification
    2. Preparation

    3. 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
    1. 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
  • 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
    • OS and hardware level
      • hsdis-HotSpot Dis Assembler
        • implemented via the lock instruction on Windows
  • 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

JVM Reordering Rules

  • happens-before principle

    • JLS17.4.5
  • as if serial

Object Memory Layout

  • What is the process of creating an object?

    1. class loading
    2. class linking()
    3. class initializing
    4. allocate memory for the object
    5. assign default values to member variables
    6. invoke the constructor
      1. assign initial values to member variables in order
      2. execute the constructor statements
  • How are objects laid out in memory?

    • VM configuration
    • Ordinary object
      1. object header markword 8
      2. ClassPointer
      3. Instance data
        • Reference types: 4 bytes with -XX:+UseCompressedOops, 8 bytes without
          • ordinary object pointers
      4. Padding for alignment to a multiple of 8
    • Array object
      1. object header markword 8
      2. ClassPointer
        • -XX:+UseCompressedOops enabled: 4 bytes; disabled: 8 bytes
      3. Array length: 4 bytes
      4. Array data
      5. alignment to a multiple of 8
  • What exactly does the object header include?

    • Obtained via the JavaAgent mechanism
      • Instrumentation
        • getObjectSize
    • markword
      • unlocked state
      • lightweight lock
      • heavyweight lock
      • GC mark
      • biased lock
  • How are objects located?

    • Reference
    • Handle pool
      • Indirect pointer: better for GC
        • Object
        • Class
    • 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

Rules for Hotspot Enabling Compressed Oops

  1. Below 4G, compression is simply disabled
  2. 4G-32G, compressed ClassPointers/Oops enabled by default
  3. 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

      1. Frame: stack frame
        • Local Variable Table
        • Operated Stacks
        • Dynamic Linking
        • Return Address
      2. one method corresponds to one 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
        1. Perm Space(< 1.8)
          • string constants live here
          • not cleaned up by Full GC
          • size fixed at startup and cannot change
        2. Meta Space(>=1.8)
          • string constants live in the heap
          • can be cleaned up by Full GC
          • if unset, the maximum is physical memory

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
    • 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 Algorithms
      • Mark-Sweep
        • two passes
      • Copying
        • one pass
      • Mark-Compact
        • two passes
  • 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
  • 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

    • 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

    • ZGC

    • G1

  • Algorithm for the Remark phase

    • tri-color marking algorithm
      • white, gray, black
    • during concurrent marking

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