Cabbage Java self study room covers core knowledge

The path to Becoming a Java Engineer Is the path to becoming a Java engineer.

1. Class loading mechanism

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.

1.1. Life cycle of a class (seven phases)

The order of the five stages of load, validation, preparation, initialization and unload is determined. The parsing phase can start after initialization (run-time binding or dynamic binding or late binding).

There are five cases in which classes must be initialized (and loading, validation, and preparation naturally need to be done before that) :

  1. Initialization is triggered when four bytecode instructions — new, getstatic, putstatic, or Invokestatic — are not initialized. Usage scenarios: Instantiate an object with the new keyword, read a static field of a class (except static fields that are modified by final and have put the result into the constant pool at compile time), and call a static method of a class.
  2. When a reflection call is made to a class using the methods of the java.lang.Reflect package.
  3. When initializing a class, if the parent class is not initialized, the initialization of the parent class is triggered first.
  4. When the virtual machine starts, the user specifies a main class (the one containing the main() method) to load, and the virtual machine initializes this main class.
  5. When using JDK 1.7 dynamic language support, if a Java lang. Invoke. The final analytical results REF_getStatic MethodHandle instance, REF_putStatic, REF_invokeStatic method handles, If the class to which the method handle corresponds has not been initialized, initialization must be triggered first.

1.2. The loading process of classes

Class loading process: load -> Connect -> initialize. The connection process can be divided into three steps: verify -> prepare -> parse.

1.2.1. The loading

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

  1. Get the binary stream (ZIP package, network, operation generation, JSP generation, database read) that defines the subclasses through the fully qualified name of a class.
  2. Transform the static storage structure represented by this byte stream into the runtime data structure of the method area.
  3. Generate a java.lang.Class object in memory that represents the Class and acts as an access point for methods to the Class’s various data.

Array classes are special: The array class itself is not created by the classloader; it is created directly by the Java virtual machine. However, array classes and class loaders are still closely related, because array classes are ultimately created by the class loader. Array creation is as follows:

  1. If the component type of the array is a reference type, it is recursively class-loaded.
  2. If the component type of the array is not a reference type, the Java virtual machine marks the array for bootstrap classloader association.
  3. The visibility of an array class is the same as that of its component type. If the component type is not a reference type, the visibility of the array class defaults to public.

The java.lang.Class object of the in-memory instance exists in the method area. As an external interface for the program to access these types of data in the method area. Parts of the load and connect phases intersect, but the start times remain sequential.

1.2.2. Connections

Connect: Merges the binary data of an in-memory class into the virtual machine’s runtime environment.

(1) Verification: is the first step of connection, to ensure that the information contained in the byte stream of the Class file meets the requirements of the current VIRTUAL machine.

File format validation

  1. Does it start with the magic number 0xCAFEBABE
  2. Check whether the major and minor versions are within the processing range of the current VM
  3. Constants in the constant pool have types that are not supported constants (check the constant tag flag)
  4. Is there any index value that points to a constant that does not exist or that does not conform to a type
  5. CONSTANT_Utf8_info whether there is data in the constant that does not conform to UTF8 encoding
  6. Additional information about whether the sections in the Class file themselves have been deleted

Only after passing the verification in this stage, the byte stream will enter the method area of memory for storage, so the following three verification stages are all based on the storage structure of the method area, and will not directly operate the byte stream.

Metadata validation

  1. Does this class have a parent (other than java.lang.object)
  2. Does the parent of this class inherit from a class that is not allowed to inherit (final modified classes)?
  3. If the class is not abstract, does it implement all the methods required by its parent or interface
  4. Whether a field or method in the class conflicts with the parent class (overwriting final fields in the parent class, with improper overloading)

This stage is mainly to semantic verification of metadata information of the class to ensure that there is no metadata information that does not conform to Java language specifications.

Bytecode verification

  1. Ensure that the data type of the operand stack and the sequence of instructions work together at any time (no longer reading an int)
  2. Ensure that jump instructions do not jump to bytecode instructions outside the method body
  3. Ensure that type conversions in the method body are valid (it is safe to assign a subclass object to a superclass data type, and the reverse is illegal)

This is the most complex stage in the validation process, and the main purpose is to determine that the program semantics are legitimate and logical through data flow and control flow analysis. In this phase, the method body of the class is verified and analyzed to ensure that the methods of the verification class do not cause events that harm VM security during running.

Symbolic reference verification

  1. Whether a class can be found for a fully qualified name described by character creation in a symbol reference
  2. Whether or not a field descriptor for a character method exists in the specified class, and the methods and fields described by the simple name
  3. The accessibility of classes, fields, and methods in symbolic references (private, protected, public, default) is accessible to the current class

The final stage of validation occurs when the sprint converts a symbolic reference to a direct reference, which takes place during the parse phase, the third stage of the join. Symbolic reference validation can be thought of as checking the match of information outside the class itself (various symbolic references in the constant pool), as well as the above mentioned. Symbolic reference purpose is to ensure normal execution parsing action, if not through reference symbol verification will throw a Java lang. IncompatibleClass. ChangeError abnormal subclass. Such as Java. Lang. IllegalAccessError, Java. Lang. NoSuchFieldError, Java. Lang. NoSuchMethodError, etc.

(2) Preparation: This stage formally allocates memory for the class and sets the initial values of class variables.

public static int value = 1127;
Copy the code

This code is 0 after the initial value is set because no Java methods have been executed yet. The putStatic instruction that assigns value to 1127 is stored in the clinit() method after the program is compiled, so value is assigned during initialization.

Zero values for basic data types:

The data type Zero value The data type Zero value The data type Zero value
int 0 boolean false long 0L
float 0.0 f short (short) 0 double 0.0 d
char ‘\u0000’ reference null byte (byte) 0

Special case: If the ConstantValue attribute exists in the field attribute table of a class field, the VM will set value to 1127 based on the ConstantValue setting during the preparation phase.

(3) Resolution: This stage is the process in which the virtual machine replaces symbolic references in the constant pool with direct references.

  1. Symbolic reference:

Symbolic references describe the referenced object as a set of symbols that can take any form of literal. 2. Direct reference: A direct reference can be a pointer to a target, a relative offset, or a handle that can be indirectly located to the target. Direct reference and quick memory layout implementation related resolution actions are mainly for class or interface, field, class method, interface method, method type, method handle, and call point qualifier 7 class symbol references, corresponding to the 7 constant types in the constant pool.

1.2.3. 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.

1.2.4. Uninstallation of classes

  1. 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.
  2. Classes loaded by user-defined class loaders can be unloaded.

1.3. Class loader

From the perspective of the Java virtual machine, there are only two types of loaders: a startup class loader (implemented in C++ as part of the virtual machine); The other is a loader for all other classes (implemented in Java, independent of the virtual machine and fully inherited from java.lang.classloader).

1.3.1. Parental delegation model

When a classloader receives a classload request, it first does not load the information about the class itself

Requests are forwarded to the parent class loader, up. So all class loading requests are passed to the parent class loader, and only if the parent class loader fails to load the required 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.

  1. Start the classloader:

Load classes in lib or by -xbootclasspath.

  1. Extended class loaders:

Load classes in lib/ext or the path specified by the java.ext.dirs system variable.

  1. Reference program class loader:

The ClassLoader is responsible for loading the library specified on the user’s path.

Benefits of the parent delegation model:

Improve system security. User-defined class loaders cannot load reliable classes that should be loaded by the parent loader. (For example, if a user defines a 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 and stops loading it.)

Characteristics of the parental delegation model:

  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. If it cannot find the data, the Class loader reads the data from the Class file, converts it into a Class object, and stores it in the cache.

1.3.2. User-defined class loaders

  1. Inherit this
  2. 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?

  1. You can load a class file from a specified location, such as a database or cloud
  2. 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.

1.3.3. Class loading mechanism and interface

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

The path to Becoming a Java Engineer Is the path to becoming a Java engineer.