Backend Development 14 min read

Understanding Java Object Creation, JVM Memory Layout, and Class Loading Process

This article explains how Java creates objects with the new operator, details the JVM's stack and heap memory model, describes class loading and the role of Class objects, and compares newInstance with new, providing code examples and visual diagrams for deeper comprehension.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding Java Object Creation, JVM Memory Layout, and Class Loading Process

Creating objects in Java using new is straightforward, but the underlying JVM mechanisms—including memory allocation, class loading, and initialization—are crucial for mastering reflection and dynamic proxies.

JVM Memory

The JVM memory model consists of two main parts:

Stack memory stores primitive data and references to objects; it is fast because data can be accessed directly.

Heap memory stores the actual objects and arrays and is managed by the garbage collector. When an object is created, a reference is placed on the stack pointing to the heap allocation.

Class Loading and .class Files

During compilation, a Java source file is turned into a .class byte‑code file that the JVM can read. The class loader then loads this file into memory, creating a Class object that describes the class.

Knowledge Extension: Class Object

The class loader loads class metadata into the Metaspace and creates a Class object that represents the class at runtime. This object can be used for reflection and dynamic proxy creation.

The Class object provides a newInstance() method, which ultimately invokes the no‑argument constructor of the class.

Class cls1 = new Class(Dog.class.getClassLoader());
Class cls2 = new Class(Cat.class.getClassLoader());
Class cls3 = new Class(People.class.getClassLoader());

JVM Generates .class Files

When a Java file is compiled, the compiler produces a .class file that the class loader later reads and transforms into a binary stream loaded into the Metaspace.

Class Loader Loads .class Files

When the JVM encounters a new instruction, it checks the constant pool for a symbolic reference to the class. If the class has not been loaded, linked, and initialized, the class loader performs these steps.

Knowledge Extension: Class Object (continued)

The Class object contains metadata such as class name, methods, and interfaces. Its newInstance() method creates an object via reflection.

@CallerSensitive
public T newInstance() throws InstantiationException, IllegalAccessException {
    if (System.getSecurityManager() != null) {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
    }
    if (cachedConstructor == null) {
        if (this == Class.class) {
            throw new IllegalAccessException("Can not call newInstance() on the Class for java.lang.Class");
        }
        try {
            Class
[] empty = {};
            final Constructor
c = getConstructor0(empty, Member.DECLARED);
            java.security.AccessController.doPrivileged(new java.security.PrivilegedAction
() {
                public Void run() {
                    c.setAccessible(true);
                    return null;
                }
            });
            cachedConstructor = c;
        } catch (NoSuchMethodException e) {
            throw (InstantiationException) new InstantiationException(getName()).initCause(e);
        }
    }
    Constructor
tmpConstructor = cachedConstructor;
    int modifiers = tmpConstructor.getModifiers();
    if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
        Class
caller = Reflection.getCallerClass();
        if (newInstanceCallerCache != caller) {
            Reflection.ensureMemberAccess(caller, this, null, modifiers);
            newInstanceCallerCache = caller;
        }
    }
    try {
        return tmpConstructor.newInstance((Object[]) null);
    } catch (InvocationTargetException e) {
        Unsafe.getUnsafe().throwException(e.getTargetException());
        return null;
    }
}

Key Differences Between Class.newInstance() and new :

newInstance requires the class to be already loaded; new triggers loading if necessary.

Class.newInstance() can only invoke a no‑argument constructor, while new can use any constructor.

newInstance is a reflection method; new is a language keyword that directly creates an object.

Example of Class.newInstance() throwing InstantiationException when the class lacks a no‑arg constructor:

// Dog class only has a constructor with a String argument
Class c = Class.forName("com.service.ClassAnalysis.Dog");
Dog dog = (Dog) c.newInstance(); // throws InstantiationException

Using Constructor.newInstance() allows passing arguments and invoking any constructor, including private ones.

// Dog class has a constructor with a String argument
Constructor cs = Dog.class.getConstructor(String.class);
Dog dog = (Dog) cs.newInstance("Little Black"); // works fine

Linking and Initialization

During this phase, static variables are allocated memory and given default values (e.g., 0 for int, null for references). Then explicit initializers and static blocks are executed.

public static int i = 666; // default value is actually 0 until initialization
public static Integer ii = new Integer(666); // default is null until initialization

Static blocks run after static variable allocation:

static {
    System.out.println("Dog static block");
}

After linking and initialization, the class is ready for object instantiation.

Creating an Instance

When the class is loaded, the JVM allocates memory for the new object (including fields from superclasses), sets default values, then runs instance initialization code (instance blocks, constructors) from parent to child.

Dog dog1 = new Dog("Wangcai");
Dog dog2 = new Dog("Xiao Hei");
Class c = Class.forName("com.service.classload.Dog");
Dog dog3 = (Dog) c.newInstance();
System.out.println(dog1.getClass() == dog2.getClass()); // true
System.out.println(dog1.getClass() == dog3.getClass()); // true

The article emphasizes that understanding these concepts—class loaders, the Class object, stack vs. heap memory, and static/instance initialization—greatly aids in mastering reflection, dynamic proxies, and frameworks such as Spring.

Explore class loaders for deeper insight.

Master the Class object and its role in reflection.

Understand stack and heap memory differences.

JavaJVMreflectionObject CreationClass Loading
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login 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.