Note source: Silicon Valley JVM complete tutorial, millions of playback, the peak of the entire network (Song Hongkang details Java virtual machine)

Update: gitee.com/vectorx/NOT…

Codechina.csdn.net/qq_35925558…

Github.com/uxiahnan/NO…

[TOC]

2. Class loading subsystem

2.1. Overview of memory structure

  • The Class file
  • Class loading subsystem
  • Runtime data area
    • Methods area
    • The heap
    • Program counter
    • The virtual machine stack
    • Local method stack
  • Execution engine
  • Local method interface
  • Local method library

If you want to write a Java virtual machine by hand, what are the main structures to consider?

  • Class loader
  • Execution engine

2.2. Class loaders and the loading process of classes

Class loader subsystem

  • The classloader subsystem is responsible for loading Class files from the file system or network. Class files have specific file identifiers at the beginning of the file.
  • The ClassLoader is only responsible for loading the class file, and whether it can run is determined by the Execution Engine.
  • The loaded class information is stored in a piece of memory called the method area. In addition to Class information, the method area stores runtime constant pool information, possibly including string literals and numeric constants (this constant information is a memory map of the constant pool portion of the Class file)

Class loader ClasLoader role

  • A class file exists on the local hard disk, and can be interpreted as a template drawn on paper by the designer, which is eventually loaded into the JVM to instantiate n identical instances from this file.
  • The class file is loaded into the JVM, called the DNA metadata template, and placed in the method area.
  • In the.class file ->JVM-> eventually becoming the metadata template, this process requires a transport (class Loader) that acts as a Courier.

Class loading process

/** * sample code */
public class HelloLoader {
    public static void main(String[] args) {
        System.out.println("Hello World!"); }}Copy the code

Use a flowchart to represent the sample code above:

Loading stage

    1. Gets the binary byte stream that defines a class by its fully qualified name
    1. Transform the static storage structure represented by this byte stream into the runtime data structure of the method area
    1. Generate a java.lang.Class object in memory that represents the Class and acts as an access point for the Class’s various data in the method area

Added: How to load class files

  • fromThe local systemDirect loading in
  • throughnetworkObtain a Web Applet
  • From the zipCompressed packageRead, become the future jar, WAR format basis
  • Runtime compute generation, most commonly used:Dynamic agent technique
  • The file is generated by other files. Typical scenarios:The JSP application
  • From the proprietaryThe database.class file, relatively rare
  • fromEncrypted file, a typical protection against Class files being decompiled

Link phase

  • Verify:
    • Objective To ensure that the byte stream in the subensure Class file meets the requirements of the CURRENT VM, ensuring the correctness of the loaded Class and not compromising VM security.
    • There are four main types of validation,File format verification, metadata verification, bytecode verification, symbol reference verification.
  • Prepare for:
    • Allocates memory for a class variable and sets its default initial value, zero.
    • Static with final is not included here, because final is allocated at compile time and initialized explicitly during preparation;
    • There is no initialization for instance variable allocationClass variables are allocated in the method area, while instance variables are allocated in the Java heap along with the object.
  • Resolve (Resolve):
    • The constant poolSymbolic references are converted to direct referencesIn the process.
    • In fact, parsing operations are often performed with the JVM after initialization.
    • A symbolic reference is a set of symbols that describe the referenced object. The literal form of symbolic references is clearly defined in the Class file format of the Java Virtual Machine Specification. A direct reference is a pointer to a target directly, a relative offset, or a handle to the target indirectly.
    • Parsing actions are for classes or interfaces, fields, class methods, interface methods, method types, and so on. Corresponding to CONSTANT_Class_info, CONSTANT_Fieldref_info, and CONSTANT_Methodref_info in the constant pool.

Initialization phase

  • The initialization phase is the execution of the class constructor method <clinit>().
  • This method does not need to be defined and is a combination of the statements in the static code block and the assignment actions of all class variables that the Javac compiler automatically collects in a class.
  • Constructor methods execute instructions in the order in which statements appear in the source file.
  • <clinit>() is different from the constructor of the class.(Correlation: constructor is <init>() from the virtual machine perspective)
  • If the class has a parent class, the JVM guarantees that

    () of the parent class has been executed before

    () of the subclass is executed.

  • The virtual machine must ensure that a class’s

    () method is locked synchronously in multiple threads.

2.3. Class loader classification

The JVM supports two types of classloaders. Bootstrap ClassLoader and User-defined ClassLoader respectively.

A custom ClassLoader is conceptually a class of class loaders defined by a developer in a program, but the Java Virtual Machine specification does not define it this way. Instead, it classifies all classloaders derived from the abstract ClassLoader as custom classloaders.

No matter how classloaders are classified, the most common class loaders in our programs are always only three, as follows:

The relation between the four here is the relation of inclusion. It’s not a hierarchy, it’s not an inheritance.

2.3.1. Built-in loader of the VM

Start the ClassLoader (Bootstrap ClassLoader)

  • This class loading is implemented in C/C++ and is nested within the JVM.
  • It is used to load Java’s core libraries (JAVA_HOME/jre/lib/rt.jar, resources.jar, or sun.boot.class.path) to provide classes that the JVM itself needs
  • Does not inherit from ava.lang.ClassLoader. There is no parent loader.
  • Loads extension classes and application classloaders and specifies them as parent classloaders.
  • For security reasons, Bootstrap starts the class loader to load only classes whose package names start with Java, Javax, and Sun

Extension ClassLoader

  • Java language, implemented by sun.misc.Launcher$ExtClassLoader.
  • Derived from the ClassLoader class
  • The parent class loader is the initiator class loader
  • Load the class libraries from the directory specified by the java.ext.dirs system property, or from the JRE /1ib/ext subdirectory (extension directory) of the JDK installation directory. If user-created jars are placed in this directory, they will also be automatically loaded by the extended class loader.

Application class loader (System class loader, AppClassLoader)

  • Java language by sun. Misc. LaunchersAppClassLoader implementation
  • Derived from the ClassLoader class
  • The parent class loader is the extension class loader
  • It is responsible for loading the class libraries under the path specified by the environment variable classpath or the system property java.class.path
  • Class loaders are the default class loaders in your programIn general, Java application classes are loaded by it
  • The class loader can be obtained by using the ClassLoader#getSystemclassLoader() method

2.3.2. User-defined class loaders

In everyday Java application development, the loading of classes is almost carried out by the above three types of loaders together. If necessary, we can also customize the class loaders to customize the way the class is loaded. Why custom class loaders?

  • Isolation load class
  • Modify the way classes are loaded
  • Extended load source
  • Preventing source code leakage

User-defined class loader implementation steps:

  1. Developers can implement their own classloaders by inheriting the abstract ava.lang.ClassLoader class to meet specific needs
  2. Before JDK1.2, it was common to inherit the ClassLoader class and rewrite the loadClass() method to implement custom classloading classes. However, after JDK1.2, it is no longer recommended to override the loadClass() method. Instead, I suggest that you write your custom classloading logic in the findClass() method
  3. When writing a custom class loader, if you don’t have too complicated requirements, you can inherit the URLClassLoader class directly. This way, you can avoid writing the findClass() method and the way to get the bytecode stream, making the custom class loader writing simpler.

2.4. Usage instructions of ClassLoader

The ClassLoader class is an abstract class, and all subsequent classloaders inherit from it (excluding the launcher ClassLoader).

Sun.misc.Launcher is a portal application for the Java virtual machine

How to obtain a ClassLoader

  • Method 1: Obtain the current ClassLoader

    clazz.getClassLoader()
    Copy the code
  • Method 2: Get the ClassLoader of the current thread context

    Thread.currentThread().getContextClassLoader()
    Copy the code
  • Method 3: Obtain the ClassLoader of the system

    ClassLoader.getSystemClassLoader()
    Copy the code
  • Method 4: Get the caller’s ClassLoader

    DriverManager.getCallerClassLoader()
    Copy the code

2.5. Parent delegation mechanism

The Java virtual machine loads class files on demand, which means that it loads its class files into memory to generate class objects when the class is needed. In addition, when loading a class file, the Java VIRTUAL machine adopts the parental delegation mode, that is, the request to the parent class processing, which is a kind of task delegation mode.

The working principle of

  • 1) If a classloader receives a classload request, it does not load the request itself. Instead, it delegates the request to the parent class’s loader.
  • 2) If the parent class loader also has its parent class loader, then further delegate up, recursively, the request will eventually reach the top level of the start class loader;
  • 3) If the parent class loader can complete the task, it returns successfully. If the parent class loader cannot complete the task, the child loader will try to load itself. This is the parent delegate mode.

For example,

Jar is implemented based on the SPI interface, so at load time, the parent delegate will be done. Finally, the SPI core class will be loaded from the root loader, then the SPI interface class will be loaded, and then the reverse delegate will be done. The implementation class jdbc.jar is loaded through the thread context class loader.

advantage

  • Avoid reloading classes
  • Protect program security and prevent the core API from being tampered with
    • Custom class: java.lang.string
    • Custom class: java.lang.ShkStart (error: prevents creation of java.lang classes)

Sandbox security mechanism

Java \lang\String. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \ string. jar: java.lang \String. This is because the string class is loaded in the rt.jar package. This ensures the protection of the Java core source code, which is called sandbox security.

2.6. Other

How do I tell if two class objects are the same

There are two requirements to indicate whether two class objects are the same class in the JVM:

  • The full class name of the class must be consistent, including the package name.
  • The ClassLoader (ClassLoader instance object) that loads this class must be the same.

In other words, in the JVM, even if these two class objects come from the same class file and are loaded by the same virtual machine, they are not equal as long as the ClassLoader instance objects that loaded them are different.

A reference to the class loader

The JVM must know whether a type is loaded by the boot loader or by the user class loader. If a type is loaded by a user class loader, the JVM stores a reference to that class loader in the method area as part of the type information. When resolving a reference from one type to another, the JVM needs to ensure that the classloaders for both types are the same.

Active and passive use of classes

Java programs use classes in active and passive ways.

Active use, and divided into seven cases:

  • Create an instance of the class

  • Accesses or assigns a value to a static variable of a class or interface

  • Call a static method of a class

  • Reflection (e.g. Class.forname (” com.atguigu.test “))

  • Initialize a subclass of a class

  • Classes that are identified as startup classes when the Java virtual machine starts

  • Dynamic language support starting with JDK 7:

    Java. Lang. Invoke. MethodHandle instance of analytical results

    REF_getStatic, REF_putStatic, and REF_invokeStatic handles are initialized if their corresponding classes are not initialized

Except for these seven cases, any other way of using A Java class is considered a passive use of the class and does not result in class initialization.