JVM-ClassLoader

Class Loader Subsystem ensures that classes are loaded safely, lazily, and hierarchically, enabling Java’s security, modularity, and runtime flexibility.


Why we need JVM

JVM is responsible for making Java program Platform Independent,

We write a Java Code (.java) --then--> compiler (javac) --compile it and create --> Byte

Code (.class) --then--> Java Interpreter convert into machine code

How JAVA Runs the Application







JVM Architecture



Think of JVM as 4 major pillars:

1️⃣ Class Loader Subsystem
2️⃣ Runtime Data Areas (Memory)
3️⃣ Execution Engine
4️⃣ Native Interface & Libraries

Class Loader Subsystem

The Class Loader Subsystem perform three part:
  1. Loading
  2. Linking
  3. Initialization

What Loading does

JVM locates and reads a .class files and create an in-memory representation of that class.

When JVM sees a reference like: 

new User();

Then:

  1. It finds the fully qualified class name
  2. Asks a class loader to load it.
  3. Reads bytecodes from:
    1. File System
    2. JAR
    3. Network (rare)
  4. Stores class metadata into MetaSpace

    

Types of Class Loader

It follows parent delegation model:

  • Bootstrap or Priomordial → serves as the parent of all the other ClassLoader instances and it is for loading JDK internal classes; eg. java.lang.*, java.util.*   

  • Extension or Platform (from Java9) → child of the bootstrap class loader and takes care of loading the standard core java classes; eg. java.sql, java.xml 

  • Application or System → child of the extension class loader and load your application-level classes; 

And because of parent delegation model we can achieve security, lower memory usage and better performance.

For instance, 

We have String class which is core java class so Bootstrap class loader will load this class and if you write an explicit String class in the same package java.lang.* then JVM will throw SecurityException, so that means it prevents the Hacking of Core API and prevent the malicious replacement of String, System, ClassLoader.

A class is loaded when:

  • new MyClass() is used
  • A static method is called
  • A static field is accessed
  • The class is explicitly loaded using:
    • Class.forName("MyClass");
class A {
    static {
        System.out.println("A loaded");
    }
}
class B {
    static {
        System.out.println("B loaded");
    }
}
public class Test {
    public static void main(String[] args) {
        new A();
    }
}

Steps                    JVM Action              
JVM starts             Only Test is loaded   
main() runs           JVM sees new A()    
A referenced          A is loaded now    
B never used         B is never loaded  




This is on-demand loading and use lower memory, better performance and scalability

What happens if on-demand loading FAILS?

Failure 1: .class not found
ClassNotFoundException

Occurs when: Class.forName("MissingClass");

Failure 2: Class existed earlier, now missing
NoClassDefFoundError

Occurs when:
  • Class was present during compile
  • Missing at runtime

How do we manage / control this?

Developer actions

  1. Correct classpath
  2. Dependency management (Maven/Gradle)
  3. Avoid circular dependencies

What Linking does

After Loading, the class is not executable yet

Linking has 3 sub-steps

Verify

What happens?

JVM checks:

  • Binary representation is structurally correct
  • .class file is generated by valid compiler
  • .class file is formatted properly
  • Illegal memory access

WHY?

  • Prevent malicious or corrupted bytecode
  • Ensure JVM safety

If it fails: JVM throw java.lang.VerifyError

Prepare

What happens?

  • Static variable or Class leve variables are allocated memory
  • Default values are assigned to the variables

Resolution - Optional

What happens?

  • Symbolic references replaced with direct references
  • Method calls linked to actual implementations
Resolution may happen:
  • During linking
  • Or lazily at runtime


What Initialization does

  • In this phase all allocated static variables are assigned with actual values defined in code.
  • Class variables are assigned with their original values
  • Static block execution in top to bottom or child to parent manner
Note: And that's why static block execute first because it comes into the picture in initialization phase before instance creation

WHY Initialization Is Separate

  • Allows lazy class loading
  • Improves startup performance
  • Avoids unnecessary execution

Memory Interaction Summary

Phase                Memory Area 
Loading             Metaspace     
Linking              Metaspace     
Initialization       Stack + Heap 

What Happens If the Class Loader Breaks?

When the Class Loader Subsystem fails, the JVM cannot correctly load, link, or manage classes, and this directly impacts application stability, memory, security, and uptime.

Comments

Popular posts from this blog

From Power ON → Firmware → OS Kernel → Process Creation → JVM → Bytecode Execution, every layer matters when you’re designing: