Fundamentals 41 min read

Unlocking JVM Secrets: Deep Dive into Memory, GC, Class Files, and Method Dispatch

This comprehensive guide explores the inner workings of the Java Virtual Machine, covering memory regions, garbage‑collection algorithms, class‑file structure, bytecode instructions, class loading mechanisms, and method dispatch strategies, providing clear explanations and code examples for developers seeking a deeper understanding of JVM fundamentals.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
Unlocking JVM Secrets: Deep Dive into Memory, GC, Class Files, and Method Dispatch

01 Introduction

Inspired by the third edition of "Deep Understanding JVM", this note reviews key JVM concepts.

02 Java Memory Areas and Overflows

The JVM memory is divided into several regions: Heap (created with -Xmx and -Xms), Method Area (class metadata, constant pool, code cache; stored in Metaspace after Java 8), Direct Memory (allocated via NIO), and thread‑local areas such as Program Counter , JVM Stack , Native Method Stack , and Thread‑Local Memory .

Heap : stores objects and arrays, managed by GC.

Method Area : holds class definitions and static data.

Direct Memory : off‑heap memory used by NIO.

Thread‑Local Memory : includes PC, JVM stack, and native stack.

Object Layout

Each object consists of a Mark Word , a Class Pointer , optional array length, the actual fields, and alignment padding. Tools like jol can inspect this layout.

public class User {
    private int age = -1;
    private String name = "unknown";
}
// java -jar jol-cli.jar internals -cp . com.jol.User

05 JVM Objects

Object creation involves allocating heap memory, optionally using a Thread‑Local Allocation Buffer (TLAB) for fast thread‑local allocation, zero‑initializing fields, setting the object header, and invoking the constructor.

06 Garbage Collection and Memory Allocation

GC solves three sub‑problems: which objects are collectible, when to collect, and how to collect. Common algorithms include reference counting, reachability analysis, and various generational strategies.

GC Algorithms

Mark‑Sweep : marks reachable objects then sweeps the rest; can cause fragmentation.

Mark‑Copy : copies live objects to a new region, eliminating fragmentation but requiring extra space.

Mark‑Compact : moves live objects to one side of the heap, then reclaims the free space.

Garbage Collectors

Typical collectors:

Serial : single‑threaded, pauses all user threads.

Parallel (Throughput‑Focused) : multiple threads, configurable pause time.

CMS (Concurrent Mark‑Sweep) : low‑pause collector with phases: initial mark, concurrent mark, remark, and concurrent sweep.

G1 : region‑based collector that targets pause time goals and reduces fragmentation.

07 Class File Structure

A .class file starts with the magic number 0xCAFEBABE, followed by version, constant pool, access flags, this/super class indices, interfaces, fields, methods, and attributes.

ClassFile {
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;
    cp_info constant_pool[constant_pool_count-1];
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;
    field_info fields[fields_count];
    u2 methods_count;
    method_info methods[methods_count];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

Key constant pool entries include CONSTANT_Utf8_info, CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_NameAndType_info.

Attributes

Code : contains bytecode, max stack, max locals, exception table, and sub‑attributes.

LineNumberTable : maps bytecode offsets to source lines.

LocalVariableTable : records local variable names and scopes.

08 Bytecode Instructions

JVM bytecode operates on an operand stack and local variable array. Instructions are grouped into loading/storing, arithmetic, type conversion, object creation/access, stack manipulation, control flow, method invocation, and exception handling.

// Load constant 5 and store into local variable 0
iconst_5
istore_0

09 Class Loading

Class loading follows the delegation model : a loader first asks its parent to load a class; if the parent cannot, the loader attempts to define the class itself. The process includes loading, verification, preparation (allocating static fields), resolution (turning symbolic references into direct references), and initialization (executing <clinit>).

Class Loaders

Typical hierarchy: Bootstrap → Extension → Application → custom loaders.

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClassOrNull(name);
            }
            if (c == null) {
                c = findClass(name);
            }
        }
        if (resolve) resolveClass(c);
        return c;
    }
}

10 Method Execution Engine

Each method invocation creates a stack frame containing a local variable array, an operand stack, and a return address. The operand stack is used for all intermediate calculations.

Method Dispatch

Java uses static (compile‑time) dispatch for overloaded methods and dynamic (runtime) dispatch for overridden instance methods. The JVM resolves invokevirtual based on the actual object's class, consulting the class's virtual method table (vtable).

public class DynamicDispatch {
    static abstract class Human { protected abstract void f(); }
    static class Man extends Human { protected void f() { System.out.println("Man f()"); } }
    static class Woman extends Human { protected void f() { System.out.println("Woman f()"); } }
    public static void main(String[] args) {
        Human h = new Man();
        h.f(); // dynamic dispatch selects Man.f()
    }
}

11 Summary

The note provides an overview of JVM memory layout, garbage‑collection strategies, class‑file format, bytecode, class loading, and method dispatch, offering a solid foundation for deeper JVM performance tuning and implementation studies.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JVMMemory ManagementbytecodeGarbage Collectionclass loading
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.