Memory structure
Loading process
Loading:
The process of finding byte streams and creating classes based on them.
The default boostrapClassLoader< -extClassLoader < -applicationClassLoader (arrows represent inheritance relationships) exists in the JVM and is loaded separately.
BoostrapClassLoader –> Classes in jar packages in the lib directory (and classes specified by the vm parameter -xbootCLASspath)
ExtClassloader –> classes in jar packages in the lib/ext directory of the JRE (and classes specified by the system variable java.ext.dirs)
ApplicationClassLoader –> -cp/-classpath, the path specified by the system variable java.class.path or the environment variable classpath
The parent delegate mechanism for class loaders
1. The current ClassLoader checks whether the loaded class is loaded. If it is loaded, it returns the loaded class directly.
Each class loader has its own load cache. When a class is loaded, it is put into the cache and then returned the next time it is loaded.
2. If the current classLoader does not find the loaded class in the cache, delegate the parent classLoader to load the class. The parent classLoader adopts the same strategy, first check its own cache, and then delegate the parent class to load the class until bootstrp classLoader.
3. When all the parent class loaders are not loaded, it is loaded by the current class loader and put into its own cache, so that the next time there is a load request.
Code: ClassLoader# loadClass
{ synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class<? > c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent ! = null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; }}Copy the code
Key steps
if (parent ! = null) { c = parent.loadClass(name, false); }Copy the code
When parent is not empty, it loads the class from the parent class loader first.
Scenario: If an application maliciously implements a Java base class, such as String. If the malicious class is loaded, objects created by String and methods called in String will have problems, because the parent delegate mechanism does not load malicious classes in both applications.
(It is also possible to break the parental delegation mechanism in some cases, but I won’t go into details here. Interested in Baidu and Google)
Links:
Linking is the process of merging created classes into a Java virtual machine for execution.
1. Verification phase: Ensure that the loaded class can meet the constraints of the Java virtual machine
2. Preparation phase: Allocate memory for static fields in loaded classes and add symbolic references to dependent classes (which can be defined unambiguously to specific targets).
3. Parsing phase: Parse symbolic references into actual references. If a symbolic reference points to a class that has not been loaded, or to a field or method of a class that has not been loaded, parsing triggers the loading of the class (but not necessarily the linking and initialization of the class).
Initialize the
Field assignments marked as constant values, and the process of executing the < Clinit > class constructor methods.
Initialize static variable statements.
That’s how demo.java is loaded into the JVM.
————————————————————————————————
Extension:
Class active initialization timing:
1. When the VM starts, initialize the primary class specified by the user.
2. Initialize the target class of the new instruction when encountering a new instruction for creating an instance of the target class;
3. Initialize the class of the static method when it encounters the instruction that calls the static method;
4. Initialize the class of the static field when it encounters an instruction that accesses the static field.
5. Initialization of a subclass triggers initialization of its parent class.
6. If an interface defines the default method, the initialization of the class that implements the interface directly or indirectly triggers the initialization of the interface.
7. Initialize a class when a reflection call is made to the class using the reflection API;
8. When you first call a MethodHandle instance, initialize the class to which the method points.