memory management
advancedClass Loaders
Load .class bytecode into the JVM on demand, organized in a parent-delegation hierarchy.
A class loader is the part of Java that finds a .class file and turns it into a class your program can use. Every class you write, and every class in the JDK, is loaded by one.
A library system. You ask the local branch (App loader); if they don't have it, they ask the regional library (Platform), then the national archive (Bootstrap). Books are only printed locally if no one upstream has them.
Key Concepts
1
You rarely think about this until something breaks. When it does, the error messages are some of the most
confusing in Java. This page explains the model so those messages start making sense.
2
There are three loaders, and they form a chain. The bootstrap loader is first. It loads the core
classes such as String and Object. Next is the platform loader, for the rest of the JDK. Last is the
application loader, which loads your own code from the classpath. Each loader has a parent. The chain ends
at the bootstrap loader.
StringObject
3
A loader asks its parent first. When your code needs a class, the application loader does not look for
it straight away. It asks its parent. That parent asks its own parent. Only when nobody above can find the
class does the original loader try. This is called delegation.
4
Delegation exists to protect the core classes. Suppose you create your own class called
java.lang.String. Without delegation, your version might get loaded instead of the real one. With it, the
bootstrap loader answers first and your version is ignored.
java.lang.String
5
A class is identified by its name plus its loader. This is the part that surprises people. The same
.class file, loaded by two different loaders, produces two different types. Java treats them as
unrelated. Casting one to the other fails.
.class
6
The error looks impossible when you first see it: a ClassCastException saying it cannot cast
com.example.User to com.example.User — the same name on both sides. That message means two loaders are
involved, not that something is wrong with your code.
ClassCastExceptioncom.example.User
7
Loading happens in three phases, and they are separate. First, loading: Java reads the bytes and
creates the class. Second, linking: it checks the bytecode is valid and sets static fields to their default
values (0, null). Third, initialisation: your static blocks run and static fields get their real
values.
0nullstatic
8
The gap between phases matters. A class can be loaded long before its static block runs. The block runs
on first real use, such as creating an instance or calling a static method.
static
9
Frameworks use custom loaders to keep code apart. An application server gives each deployed
application its own loader. Two applications can then use different versions of the same library without
clashing. Plugin systems work the same way.
10
There is a cost. A loader keeps every class it loaded alive in memory. If something still holds a
reference to an old loader, none of its classes can be freed. That is why redeploying an application
several times can slowly exhaust memory.
11
What the interviewer is probing.1. "Explain the delegation model." Probing: whether you know which way requests travel. Stalls:
"Loaders load classes." Moves up: a loader asks its parent first, and this is what stops your code from
replacing java.lang.String.
java.lang.String
12
2. "Can two classes have the same name?" Probing: how Java identifies a class. Stalls: "No."
Moves up: yes, if two loaders loaded them. The sign is a ClassCastException naming the same class
twice.
ClassCastException
13
3. "ClassNotFoundException or NoClassDefFoundError?" Probing: whether you can tell them apart.
Stalls: "Both mean the class is missing." Moves up: the first comes from code that looked a class up by
name. The second means the class was there when you compiled, but is missing or failed to initialise now.
14
4. "Why does redeploying repeatedly run out of memory?" Probing: what a loader holds onto. Stalls:
"A memory leak." Moves up: each deployment has its own loader, and a loader keeps all its classes alive.
One leftover reference keeps the whole set in memory.
15
5. "When would you write your own loader?" Probing: whether you know what it is for. Stalls: "For
flexibility." Moves up: to isolate plugins or tenants that need different versions of a library, or to
load classes from somewhere other than the classpath.
16
The chain and what each loader owns17
Bootstrap (native) java.base -- String, Object, Integer
^
Platform JDK modules outside the core
^
Application your classpath / module path
^
Custom (optional) plugin, web app, tenant isolation18
Lookup order: ask the PARENT first, all the way up; try
yourself only if nobody above could load it.19
Phases20
1. Loading read bytes, create the Class object
2. Linking
verify bytecode is well-formed and safe
prepare static fields get DEFAULT values (0, null)
resolve symbolic references resolved (may be lazy)
3. Initialisation static initialisers run, statics assigned
-- triggered by FIRST ACTIVE USE, not by
loading21
Error decoder22
ClassNotFoundException explicit lookup (Class.forName,
loadClass) failed -> missing jar,
wrong name
NoClassDefFoundError present at compile time, absent or
unloadable now -- OR its static
initialiser threw earlier
ExceptionInInitializerError the static initialiser threw, this
time (the informative one)
UnsupportedClassVersionError class file newer than the JVM
(e.g. compiled for 21, running 17)
LinkageError / ClassCastException naming the same class twice
same bytes, two loaders