This is the sixth day of my participation in the August More text Challenge. For details, see:August is more challenging

Class loading process

Class loading mechanism:

  • The Java VIRTUAL machine loads the data describing the Class from the Class file to the memory, verifies, converts, parses, and initializes the data, and finally forms a Java type that can be directly used by the VIRTUAL machine
  • The information described in the Class file 􏰁 eventually needs to be added to the virtual machine before it can be run and used

Class lifecycle

  • A type goes through its entire life cycle from the time it is loaded into the memory of the virtual machine to the time it is unloaded from the memory
  • There are seven stages of loading, certification, preparation, analysis, initializing, commissioning and unloading

  • The five phases of load, validation, preparation, initialization, and unload are in a defined order, and the loading process of a type must begin in that order
  • The parsing phase can in some cases begin after the initialization phase, also known as dynamic binding
  • If you think about it what does this code output?
public class SuperClass { static { System.out.println("SuperClass init!" ); } public static int value = 123; } class SubClass extends SuperClass { static { System.out.println("SubClass init!" ); } } class test { public static void main(String[] args) { System.out.println(SubClass.value); }}Copy the code

  • Solution: For static fields, only the class that defines the field directly will be initialized,
  • Therefore, a reference to a static field defined in a parent class through its child class triggers initialization only for the parent class and not for the child class

loading

Three things you need to do during the load phase

  1. Gets the binary byte stream that defines a class through its fully qualified name.
  2. Converts the static storage structure represented by this byte stream into the runtime data structure of the method area.
  3. A java.lang.Class object that represents the Class is generated in memory and is used as an entry point for various data about the Class in the method area.

validation

purpose

  • Is to ensure that the information contained in the byte stream of a Class file meets all the constraints of the Java Virtual Machine Specification
  • Ensure that this information is run as code without compromising the security of the virtual machine itself.
  1. File format validation: verify the start of magic, primary and secondary version numbers, whether constant pools are supported, whether parts of the Class file have been deleted or additional information
  2. Metadata validation: mainly semantic analysis, whether there is a parent class, whether the fields in the class conflict with the parent class (such as final fields that overwrite the parent class)
  3. Bytecode validation: Mainly determines whether the semantics are valid. Conform to logic and ensure instruction security
  4. Symbolic reference validation: Determines whether the class is missing or denied access to external classes, methods, fields, and other resources on which it depends

To prepare

purpose

  • The phase in which memory is formally allocated for variables defined in a class (that is, static variables, variables that are modified by static) and initial values are set for class variables
  • The first is that only class variables are allocated, not instance variables, which are allocated in the Java heap along with the object when it is instantiated.
  • The next is that the initial value here is “normally” a null value of the data type. Suppose a class variable is defined as:
public static int value = 123;
Copy the code
  • The initial value of the variable value after the preparation phase is 0 instead of 123 because no Java methods have been executed yet,
  • The putstatic instruction assigning value to 123 is stored in the constructor () method after the program is compiled, so the action of assigning value to 123 is not executed until the class is initialized
  • Zero values for all basic data types in Java:

parsing

purpose

  • The Java VIRTUAL machine replaces symbolic references in the constant pool with direct references
  • Symbolic References: A Symbolic reference uses a set of symbols to describe the referenced target. A symbol can be a literal in any form, as long as it can be used to locate the target without ambiguity
  • Direct References: A Direct reference is either a pointer, a relative offset, or a handle that can indirectly locate a target
  1. Class or interface resolution
  2. Field analytical
  3. Method resolution
  4. Interface Method parsing

Initialize the

purpose

  • The Java Virtual Machine actually starts executing the Java program code written in the classes, handing over control to the applications.
  • In the preparation phase, variables have been assigned once to the initial zero value required by the system, while in the initialization phase, class variables and other resources are initialized according to a subjective plan made by the programmer through the program code.
  • Let’s look at the following code:

  • The following error is displayed

  • Because the order in which the compiler collects the statements is determined by the order in which the statements appear in the source file, a static block can only be accessed by variables defined before and after the static block. The preceding static block can be assigned, but cannot be accessed

Parent delegation model

  • From the Perspective of the Java Virtual Machine, there are only two different class loaders:
  • One is the BootstrapClassLoader, and the other is the loader for all the other classes

The working process of the parent delegation model is

  • If a classloader receives a classloading request, it does not first attempt to load the class itself. Instead, it delegates the request to the parent classloader
  • This is true for each level of classloader, so all load requests should eventually be passed to the uppermost startup classloader, only if the parent loader reports that it cannot complete the load request (it cannot find the required class in its search scope)
  • The child loader will then attempt to complete the load itself.

The benefits of organizing relationships between classes in this way

  • Classes in Java have a hierarchy of priorities along with their class loaders
  • For example, the java.lang.Object class, which is stored in rt.jar, is eventually delegated to the bootstrap class loader at the top of the model.
  • Therefore, the Object class is guaranteed to be the same class in all class loader environments of the program.
  • On the other hand, if the parent delegate model is not used, and the individual class loaders load it, if the user writes a class called java.lang.object and puts it in the program’s ClassPath
  • There would be multiple different Object classes in the system, the most basic behavior of the Java type system would not be guaranteed, and the application would be a mess.

  • The above code will report the following error
Error: the main method cannot be found in class java.lang.string. Define the main method as: Public static void main (String [] args) or deployment headaches the application class must extend deployment headaches. The application. The applicationCopy the code
  • The above error occurs because when the class loader is executed, it is first handed to the parent class to load
  • If one of the parent loaders loads successfully, the downward return succeeds
  • If neither the parent nor the parent can load, an exception is reported

== How to break the parent delegate model ==

  • Thread Context ClassLoader. This ClassLoader can be set using the setContext-ClassLoader() method of the java.lang.thread class,
  • If it is not set when the thread is created, it will inherit one from the parent thread. If it is not set globally for the application, this class loader defaults to the application class loader.
  • With the thread context classloader, the program can do some cheating. The JNDI service uses this thread context class
  • The loader loads the required SPI service code. This is the behavior of the parent class loader asking the child class loader to complete the class loading.
  • This behavior actually breaks through the hierarchy of the parent delegate model to use the classloader in reverse, which already violates the general principles of the parent delegate model

Tomcat’s classloader architecture

== Basic needs ==

  • Java class libraries used by two Web applications deployed on the same server can be isolated from each other
  • Java class libraries used by two Web applications deployed on the same server can be shared with each other

  • Classes that can be loaded by the Common class loader can be used by Catalina class loaders and Shared class loaders
  • The classes that the Catalina class loader and the Shared class loader can load themselves are isolated from each other.
  • The WebApp class loader can use classes loaded by the Shared class loader, but individual WebAp class loader instances are isolated from each other.
  • JasperLoader only loads the Class file compiled by this JSP file.
  • It exists to be discarded: when the server detects that the JSP file has been modified, it replaces the current Jasp erLoader instance
  • And through the establishment of a new JSP class loader to achieve JSP file HotSwap function.