This article will cover nothing more than the class loading mechanism of the JVM

A concept,


The class loader reads the binary data from the class file into memory, stores it in the method area, and creates a java.lang. class object in the heap that encapsulates the data structure of the class in the method area.

ⅰ. Loading:

Find and load the binary data of the class (load the information from the class file into memory)

ⅱ. Connection:

Merges the binary data of the in-memory classes into the virtual machine’s runtime environment

1. The validation:

Ensure that the classes being loaded are correct, including:

  • Class file structure check: Check that the fixed format of Java class files is met

  • Semantic checking: Ensure that the class itself conforms to Java syntax specifications

  • Bytecode validation: Ensures that the bytecode stream can be safely executed by the Java Virtual machine. A bytecode stream is a sequence of opcodes. Each opcode is followed by one or more operands. Bytecode checking This step checks whether each opcode is valid.

  • Binary compatibility verification: Ensures that classes that reference each other are compatible.

2. Preparation:

Allocates memory for static variables of the class and initializes them to default values

3. The resolution:

Converting symbolic references in a class to direct references (such as symbolic references to methods, which consist of method names and associated descriptors). During the parsing phase, the JVM replaces the symbolic reference with a pointer, which is a direct reference, to the memory location of the class’s method in the method area.

ⅲ. Initialization:

Assign correct initial values to static variables of the class. When the value to the right of the equal sign of a static variable is a constant expression, the static code block is not called for initialization. Static initialization is called only if the value to the right of the equals sign is a run-time computed value.

2. Parental delegation model


1. Pass the classloading request up. When a classloader receives a classloading request, it first does not load the information about the class itself, but forwards the request to the parent classloader and up.

So all class loading requests are passed to the parent class loader, and only if the parent class loader does not find the desired class will the subclass loader attempt to load the class itself.

Throws a ClassNotFindException when neither the current class loader nor any parent class loader is able to load the class.

2. Significance: Improve the security of the system. User-defined class loaders cannot load reliable classes that should be loaded by the parent loader.

For example, if a user defines malicious code, the custom class loader first tells the system loader to load it. The system loader checks that the code does not conform to the specification, so it stops loading.

Defining class loaders: If a class loader can load a class, it is called defining class loaders

4. Initial class loaders: Define the class loaders and all their children as initial class loaders.

5. Runtime package:

  • A runtime package consists of classes loaded by the same classloader and with the same package name

  • Only classes belonging to the same runtime package can access classes and class members that are visible to the package (default).

  • This prevents a user-defined class from accessing the package visible members of the core library by pretending to be a class of the core library

6, loading two copies of the same class: A and B are not parent-child classloaders, and each has loaded the same class.

Three, features:


1. Full responsibility: When a class loader loads a class, other classes that that class depends on are also loaded into memory by the class loader.

2. Caching mechanism: All Class objects are cached. When a program needs to use a Class, the Class loader first looks for the data in the cache.

Two types of class loaders


JVM class loaders (3 types)

(1) Bootstrap:

  • Written in C++, the programmer cannot get this class in the program
  • Responsible for loading the core libraries of the virtual machine, such as java.lang.Object
  • No ClassLoader class is inherited

(2) Extension class loader:

  • Java written to load class libraries from the specified directory
  • The parent loader is the root class loader
  • Is a subclass of ClassLoader
  • If the user creates jar files in the specified directory, they will also be loaded by the extension loader.

(3) System loader or App loader:

  • Written in Java
  • The parent loader is the extension class loader
  • Load classes from environment variables or class.path
  • Is the default parent loader for user-defined class loads
  • Is a subclass of ClassLoader

2. User-defined class loaders:

  • A subclass of the java.lang. ClassLoader class

  • Users can customize how classes are loaded

  • The parent class loader is the system loader

  • Writing steps:

    • Inherit this
    • Override the findClass method. Load a class file from a specific location, get a byte array, and then use defineClass to convert the byte array into a class object
  • Why custom class loaders?

    • You can load a class file from a specified location, such as a database or cloud

    • Encryption: Java code can be easily decompiled. Therefore, if you need to encrypt the code, then the encrypted code cannot use the Java ClassLoader to load the class. You need to customize the ClassLoader, decrypt the class, and then load it.

PS:


Problem: Java programs can execute classes in several ways:

Active use (6 cases) : // The JVM must initialize each class on its “first active use”.

  • Create an instance of the class
  • Reads and writes static variables of a class or interface
  • Call a static method of a class
  • Get the Class from the reflection API (class.forname ())
  • Initialize a subclass of a class
  • The class that is marked as the startup class when the JVM starts (the class that contains the Main method)

This can be considered active use of the class or interface only if the static variables or methods used by the program are actually defined in the class.

2. Passive use: Except for six cases of active use, all cases are passive and do not result in class initialization.

3. The JVM specification allows classloaders to preload a class in anticipation that it will be used.

If the class file is missing or has an Error, the Linkage Error will only be reported when the program “first active use”.

If the class has not been “actively used” by the program, no error is reported.

Class loading mechanism and interface:

  • When the Java Virtual machine initializes a class, it does not initialize the interface that that class implements.
  • When an interface is initialized, the parent interface is not initialized.
  • The interface is initialized only when the program first uses a static variable of the interface.

ClassLoader: Calls the loadClass method of the ClassLoader to load a class. It is not used actively and therefore does not initialize the class.

Class uninstallation:

  • Classes loaded by the JVM’s three native loaders (root, extension, and system) are never unloaded. Because the JVM always references these classloaders, which use references to the classes they load, these Class objects are always reachable.
  • Classes loaded by user-defined class loaders can be unloaded.