Java Virtual Machine (JVM) Internals, Part 1 — Classloader

Prateek Saini
Javarevisited
Published in
5 min readJun 23, 2019

--

In this series of articles, I’ll be discussing how Java Virtual Machine works. In this article I’m going to talk about Class loading mechanism in JVM.

Java Virtual Machine is the heart of the Java Technology ecosystem. It’s the JVM which makes Java programs as ‘write once run everywhere’ thing. Like other virtual machines JVM is also an abstract computer. A Java virtual machine’s main job is to load class files and execute the bytecodes they contain.

There are multiple components of Java Virtual Machine like Classloader, Garbage Collector (Automatic memory management), Interpreter, JIT Compiler, Thread management. In this article we are going to talk about Class loader.

The Class loader loads class files from both the program and the Java API. Only those class files from the Java API that are actually needed by a running program are loaded into the virtual machine.

The bytecodes are executed in an execution engine.

What is class loading ?

Class loading is finding and loading types (classes and interfaces) at runtime dynamically. Types data are contained in binary files in class file format.

Phases of Class loading

The class loader subsystem is responsible for more than just locating and importing the binary data for classes. It must also verify the correctness of imported classes, allocate and initialize memory for class variables, and assist in the resolution of symbolic references. These activities are performed in a strict order:

  • Loading: finding and importing the binary data for a type with a particular name and creating a class or interface from that binary representation.
  • Linking: performing verification, preparation, and (optionally) resolution
  • Verification: ensuring the correctness of the imported type
  • Preparation: allocating memory for class variables and initializing the memory to default values
  • Resolution: transforming symbolic references from the type into direct references.
  • Initialization: invoking Java code that initializes class variables to their proper starting values.

Note : In addition to loading classes, a class loader is also responsible for locating resources. A resource is some data (a “.class” file, configuration data, or an image for example) that is identified with an abstract ‘/’-separated path name. Resources are typically packaged with an application or library so that they can be located by code in the application or library.

The Java Class Loading Mechanism

The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a “parent” class loader. When loading a class, a class loader first “delegates” the search for the class to its parent class loader before attempting to find the class itself.

The class loader delegation model is the graph of class loaders that pass loading requests to each other. The bootstrap class loader is at the root of this graph. Class loaders are created with a single delegation parent and look for a class in the following places:

  • Cache
  • Parent
  • Self

A class loader first determines if it has been asked to load this same class in the past. If so, it returns the same class it returned last time (that is, the class stored in the cache). If not, it gives its parent a chance to load the class. These two steps repeat recursively and depth first. If the parent returns null (or throws a ClassNotFoundException), then the class loader searches its own path for the source of the class.

Because the parent class loader is always given the opportunity to load a class first, the class is loaded by the class loader nearest the root. This also has the effect of only allowing a class loader to see classes loaded by itself or its parent or ancestors; it cannot see classes loaded by its children.

The Java SE Platform API historically specified two class loaders :

Bootstrap class loader : which loads classes from the bootstrap classpath.

System class loader : which is the default delegation parent for new class loaders and, typically, the class loader used to load and start the application.

Run-time Built-in Class Loaders (JDK 9+)

Application class loader : The application class loader is typically used to define classes on application class path. It’s default loader for JDK modules that provide tools or export tool APIs.

Platform class loader : It defines selected (based of security/permissions) Java SE and JDK modules. For e.g. java.sql

Bootstrap class loader : It defines the core Java SE and JDK modules.

The three built-in class loaders work together to load classes as follows:

  • The application class loader first searches the named modules defined to all of the built-in loaders. If a suitable module is defined to one of these loaders then that loader will load the class. If a class is not found in a named module defined to one of these loaders then the application class loader delegates to its parent. If a class is not found by its parent then the application class loader searches the classpath. Classes found on the class path are loaded as members of this loader’s unnamed module.
  • The platform class loader searches the named modules defined to all of the built-in loaders. If a suitable module is defined to one of these loaders then that loader will load the class.If a class is not found in a named module defined to one of these loaders then the platform class loader delegates to its parent.
  • The bootstrap class loader searches the named modules defined to itself. If a class is not found in a named module defined to the bootstrap loader then the bootstrap class loader searches the files and directories added to the bootstrap classpath via the -Xbootclasspath/a option (allows files and directories to be appended to the default bootstrap class path now). Classes found on the bootstrap class path are loaded as members of this loader’s unnamed module.

To see the built-in class loaders you can run the below code

With Amazon Corretto 11.0.3 installed on my machine, the above code produces the following output

ClassLoader name : appClassLoader class : jdk.internal.loader.ClassLoaders$AppClassLoaderClassLoader name : platformClassLoader class : jdk.internal.loader.ClassLoaders$PlatformClassLoaderBootstrap classloader

You can check the ClassLoader APIs here (JDK 11)

Other Useful Resources for learning Java you may like
Top 5 Courses to learn JVM internals
10 Free Courses to Learn Java from Scratch
10 Books to Learn Java in Depth
10 Tools Every Java Developer Should Know
10 Reasons to Learn Java Programming languages
10 Frameworks Java and Web Developer should learn in 2019
10 Tips to become a better Java Developer in 2019
Top 5 Java Frameworks to Learn in 2019
10 Testing Libraries Every Java Developer Should Know

--

--