JVM Class Loading Mechanism
JVM’s Class Loading Mechanism is a very core part of Java virtual machine. It determines where classes come from, how they are loaded, when they are initialized and a series of behaviors.
Overall Class Loading Process
Java class loading process can be divided into five stages:
-
Loading: Read .class file into memory, generate a java.lang.Class object. Completed by class loader, may come from local disk, network, or even dynamically generated bytecode.
-
Verification: Ensure bytecode conforms to JVM specification, guarantee runtime security. Check if format is correct, if semantics conform to regulations, if permissions are legal, etc.
-
Preparation: Allocate memory for class’s static variables, set initial default values (not explicit assignment).
-
Resolution: Convert symbolic references in constant pool to direct references. Such as: class name, field name, method signature -> actual address.
-
Initialization: Formally execute
<clinit>()method (class constructor), which is static variable initialization and static code block execution. This is the last step in class loading process, after which class can be used.
Class Loader Model
Class loaders in JVM are responsible for loading classes into JVM and maintaining a “class name - class instance” mapping table.
- Bootstrap ClassLoader: Built into JVM, implemented in C++, JAVA_HOME/lib core classes, such as java.lang.*
- Extension ClassLoader: Load extension library, JAVA_HOME/lib/ext
- App ClassLoader: Most commonly used, loads your code by default, classes under classpath
- Custom ClassLoader: Developer custom implementation, such as hot deployment, decryption, etc.
Parent Delegation Model
Before loading a class, class loader first delegates the request to parent class loader, keeps going up until Bootstrap. Only when parent class loader cannot load, will child class loader try to load.
Mechanism Functions:
- Prevent loading the same .class repeatedly. Through delegation mechanism, ask above if already loaded, if yes then don’t load again, guarantee data security.
- Ensure .class cannot be tampered with. Through delegation, won’t tamper with core .class, even if tampered won’t load. Even if loaded, won’t be the same .class object.
Class Lifecycle
Class loading (especially initialization) is only triggered when actively used:
- new instance
- Access static variable
- Call static method
- Reflection call
- Subclass initialization
Class Unloading: JVM no longer uses a class, and the ClassLoader that loaded it is recycled, then the class may be unloaded (mainly appears in containers like OSGi, Tomcat).
Tomcat’s Class Loading Mechanism
Tomcat’s class loading mechanism has made some changes compared to JVM’s class loading mechanism. It does not strictly follow the parent delegation model, or it can be said it breaks the parent delegation model.
Tomcat 8.5 default changed strict parent delegation model:
- First load specified classes from Bootstrap ClassLoader
- If not loaded, then from /WEB-INF/classes
- If not loaded, then from /WEB-INF/*.jar
- If not loaded, then sequentially from System, Common, Shared (in this final step, follows parent delegation model)