An overview of the

The virtual machine loads the class file into memory, validates, transforms, and initializes the data, and eventually forms Java types that the virtual machine can use directly

A Class file is a set of binary streams based on 8-bit bytes, without any separators between data items. When encountering data items with more than 8-bit space, they are separated into several 8-bit bytes for storage according to the way with the highest order.


Class loading subsystem working steps

  • The Class loading 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 a 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)

1. The load

1.1 When will classes be loaded

  • New, getstatic, putstatic, invokestatic bytecode instructions are encountered
  • When a class is reflected using the java.lang.reflect method
  • When a class is initialized and the parent class is not initialized yet
  • When the vm starts, the user specifies the main class
  • When using dynamic language support in JDK1.7

1.2 Where to Load it

  • Load from zip packages such as JAR,WAR, etc
  • From the network, such as applt
  • Run-time computed generation, such as “*$proxy “in java.lang.reflect.proxy, is a binary stream of the class
  • Generated by other files, such as JSPS
  • Reading from a database is a rare scenario

1.3 How do I Load it?

  • Gets the binary byte stream that defines a class by its fully qualified name;
  • Convert the static storage structure represented by this byte stream to the runtime data of the method area;
  • 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

2. The link

2.1 validation

  • To ensure that the byte stream in the class file meets the requirements of the current VM and does not compromise VM security
  • It mainly includes four kinds of verification, file format verification, source data verification, bytecode verification, symbol reference verification.

(To be added)

2.2 to prepare

  • The preparation phase is when memory is formally allocated and initial values are set for class variables
  • Class variables (modified static) are assigned instead of instance variables
  • Classes are not initialized for instance variable allocation, class variables are allocated in the method, and instance variables are allocated in the Java heap along with the object

2.3 analytical

  • The parsing phase is when the virtual machine converts symbolic references in the constant pool to direct references

A symbolic reference is: a symbolic reference describes the referenced object as a set of symbols. The symbol can be any literal, as long as it is used to unambiguously locate the target. In Java, a Java class will be compiled into a class file. At compile time, the Java class does not know the actual address of the referenced class, so it has to use symbolic references instead. For example, org.simple.People refers to org.simple.Language. At compile time, People does not know the actual memory address of Language, so it can only use the symbol org.simple.Language (assuming this, Of course, it is actually represented by a constant like CONSTANT_Class_info) to represent the address of the Language class.

A direct reference is: with a direct reference, the target of the reference must already be loaded into memory.

I. Direct Pointers to targets (for example, direct references to Class objects, Class variables, or Class methods may be Pointers to method areas)

Ii. Relative offsets (for example, direct references to instance variables and instance methods are offsets) iii. A handle that can be indirectly located to the target

  • Parsing actions are for classes or interfaces, fields, class methods, interface methods, method types, and so on. CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTAT_Methodref_info in the constant pool.
  • Analytical steps:

Class or interface resolution: the current class is A, if the symbolic reference is B, need to resolve into class or interface C to direct reference, three steps

I. If C is not an array type, the fully qualified name representing class B is passed to A, and C is loaded by A’s classloader

Ii. If C is an array type and the array contains objects, the objects will be loaded according to the rules in point 1, and then the virtual machine will generate an object representing the dimensions and elements of the array data object III. The above no exception, has already generated objects, and then verify whether A has access to C, no permissions are submitted to the Java lang. IIlegalAccessError anomalies

Field parsing: To parse a field, reference the symbol of the class or interface to which the field belongs. If an exception occurs in this step, the field fails

I. If C itself contains a reference field, the search is complete

Ii. If C implements interfaces or parent classes, recursively search each interface and parent class from bottom to top. If C contains interfaces or parent classes, the search ends iii. Search after the verification authority, without permission, the Java lang. IIlegalAccessError anomalies. If find failure, throw the Java. Lang. NoSuchFieldError anomalies

Class methods analytic: class method and interface method of symbolic reference is separate, if found method showed that C is the interface, the thrown Java. Lang. IncompatibleClassChangeError anomalies.

I. If C itself contains a reference method, the search ends

Ii. If C implements a parent class, recursively search each parent class from bottom to top. If C contains a parent class, the search ends. If C is an abstract class, it throws the Java. Lang. Abnormal AbstractMethodError iii. Search after the verification authority, without permission, the Java lang. IIlegalAccessError anomalies. If find failure, throw the Java. Lang. NoSuchFieldError anomalies

Interface methods analytic: if found method showed that C is a class, it throws Java. Lang. IncompatibleClassChangeError anomalies.

I. If C itself contains a reference method, the search ends

Ii. If parent interfaces are implemented in C, each parent interface is recursively searched from bottom to top. If parent interfaces are included, the search ends iii. Lookup fails, throwing the Java. Lang. NoSuchFieldError abnormalities, default is public interface methods, there is no access problems

3. The initialization

  • Initialization is the execution of the () method in bytecode, which is generated by combining the assignment action of a class variable in the code with a static code block (static{}). Clinit methods will not be generated without class variables or static code blocks

The instructions in the constructor methods are executed in the order in which the statements appear in the source file. The order in which the compiler collects them is determined by the order in the source file.

  • Clinit, unlike a class constructor (init), does not require an explicit call to the parent class constructor. The parent class Clinit must have been executed before the subclass’s Clinit was executed, so the first Clinit method to be loaded and executed when the virtual machine started must be of java.lang.Object
  • The virtual machine must ensure that a class’s Clinit () method is locked synchronously in multiple threads.
  • Interfaces have and do have clinit methods (interfaces have no static code, but do have initialization assignments), and the interface’s Clinit does not need to execute the parent interface’s Clinit method first.

Class loader

1. Loader introduction

  • To get the binary byte stream describing a class by its fully qualified name, this action is placed in
  • The class loader implements the loading action of a class and is used to identify a class. For any class, its uniqueness within the Java virtual machine needs to be established both by the classloader that loads it and by the class itself. Even if two classes come from the same Class file, they are not equal as long as they are loaded by different classloaders. (such as through custom loaders)
  • The JVM supports two types of loaders, BootStrap classloaders and user-defined classloaders.
  • Our most common class loaders in the program are always only three, as follows:

2. Loaders for custom classes and core libraries

  • For user-defined classes: use the system class loader AppClassLoader to load them
  • The Java core class libraries are loaded using the BootStrapClassLoader
Public static void main (String [] args) {/ / acquisition system class loader this systemClassLoader. = this getSystemClassLoader (); System.out.println(systemClassLoader); / / sun. Misc. The Launcher $AppClassLoader @ 18 b4aac2 / / access to its upper: extension class loader this extClassLoader = systemClassLoader. The getParent (); System.out.println(extClassLoader); //sun.misc.Launcher$ExtClassLoader@1540e19d ClassLoader bootstrapClassLoader = extClassLoader.getparent (); System.out.println(bootstrapClassLoader); / / null / / for user-defined class: use the default system class loader to load this this = ClassLoaderTest. Class. GetClassLoader (); System.out.println(classLoader); //sun.misc.Launcher$AppClassLoader@18b4aac2 // The String class is loaded using the bootstrap classloader. --> Java's core class libraries are loaded using the boot class loader. ClassLoader classLoader1 = String.class.getClassLoader(); System.out.println(classLoader1); //null }Copy the code

3. A 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 loads the Java core library (JAVA_HOME/jre/lib/rt. The jar/resources. The jar or sun. Boot. The class. The path under the path of content), is used to provide the JVM itself need to class
    • Does not inherit from java.lang.ClassLoader and has no parent loader
    • Loads extension classes and application classloaders and specifies them as their parent
    • 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 /lib/ext subdirectory (extension directory) of the JDK installation directory. If user-created jars are placed in this directory, they are automatically loaded by the extension class loader
  • Application class loader (System class loader, AppClassLoader)
    • Java language, implemented by sun.misc.Launcher$AppClassLoader.
    • 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
    • The class loader is the default class loader in a program. Generally speaking, Java applications are loaded by it
    • The class loader can be obtained by using the ClassLoader#getSystemClassLoader() method
Public static void main (String [] args) {System. Out. Println (" * * * * * * * * * * to start the class loader * * * * * * * * * * * * * * "); / / get BootstrapClassLoader can load the path of the API URL [] urLs = sun. Misc. The Launcher. GetBootstrapClassPath (.) getURLs (); for (URL element : urLs) { System.out.println(element.toExternalForm()); } / / from the above path choice of a class, to see what his class loader is: the bootstrap class loader this this = Provider. Class. GetClassLoader (); System.out.println(classLoader); System. Out. Println (" * * * * * * * * * * * the extension class loader * * * * * * * * * * * * * "); String extDirs = System.getProperty("java.ext.dirs"); for (String path : extDirs.split(";" )) { System.out.println(path); } / in/from the above path choice of a class, let's see what his class loader is: extension class loader this classLoader1 = CurveDB. Class. GetClassLoader (); System.out.println(classLoader1); //sun.misc.Launcher$ExtClassLoader@1540e19d }Copy the code

4. User-defined class loaders

Isolation of loading classes extends loading sources to prevent source code leakage of multiple versions of Jar packages

1. Inherit the ClassLoader class. 2

public class CustomClassLoader extends ClassLoader { @Override protected Class<? > findClass(String name) throws ClassNotFoundException { try { byte[] result = getClassFromCustomPath(name); if (result == null) { throw new FileNotFoundException(); } else { return defineClass(name, result, 0, result.length); } } catch (FileNotFoundException e) { e.printStackTrace(); } throw new ClassNotFoundException(name); } private byte[] getClassFromCustomPath(String name) {// Load the specified class from the custom path: details omitted // If the bytecode file specified by the path is encrypted, the decryption operation needs to be performed in this method. return null; }}Copy the code

5. Parent delegation

The Java virtual machine loads class files on demand, which means that it loads her class files into an in-memory generated class object when the class needs to be used. In addition, when loading a class file, the Java VIRTUAL machine adopts parental microclap mode, that is, the request is handed over to the parent class, which is a task delegation mode

protected Class<? > loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, Check if the class has already been loaded // Check if the class has already been loaded. > c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); Try {// c==null indicates that no parent class is loaded. If (parent! = null) { c = parent.loadClass(name, false); } else {// If the parent class loader is empty, the recursion is to bootStrapClassloader. //bootStrapClassloader is special and cannot get 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

5.1 The role of parental delegation mechanism

  • Prevent the same. Class from being loaded repeatedly. You can ask the delegate up there, so once it’s loaded, you don’t have to load it again. Ensure data security.
  • Ensures that the core.class cannot be tampered with. By delegating, you don’t tamper with the core clas, and if you do, you don’t load it, and if you load it, it won’t be the same.class object. Different loaders do not load the same.class object. This ensures Class execution security.

Sandbox security: Prevents malicious code from contaminating Java source code

For example, IF I define a class named String and the package is java.lang, this class belongs to JDK. Without sandbox security, this class would pollute all of my strings. But because of sandbox security, I delegate the top layer bootstrap loader to find this class. If you do not have extsion, you can delegate extsion to aapClassLoader. However, since String is the source code of JDK, it is loaded in bootstrap. Therefore, you can use the String inside the bootstrap, and do not use the rest of the String. This ensures that malicious code will not be contaminated

Active and passive use of classes

  • Create an instance of the class
  • To access or assign a value to a static variable of a class or interface
  • Call a static method of a class
  • Reflection such as class.forname (com.dsh.jvm.xxx)
  • Initialize a subclass of a class
  • Classes that are identified as startup classes when the Java virtual machine starts
  • Dynamic language support is available from JDK 7
  • When does 1.1 load classes

JVM full directory

Class loading mechanism 3. Runtime data area [PC register, vm stack, local method stack] 4. Runtime data area [heap] 5. Runtime data area [method area] 6. Temporary absence 7. Runtime data area [instantiated memory layout and access location of objects, direct memory] 8. String constant pool 10. Garbage collection [overview, related algorithms] 11. Garbage collection [related concepts] 12. Common OOM 14. JDK command line tools