1. Run time data area

1. Regional division

2. Program counter

  • Small memory space, thread private. The bytecode interpreter works by changing the value of this counter to select the next bytecode instruction that needs to be executed. Branch, loop, jump, exception handling, thread recovery and other basic functions need to be completed by the counter.
  • If a thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If the Native method is being executed, the counter value is (Undefined). This memory region is the only one where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

Java virtual machine stack

  • The thread is private and has the same life cycle as the thread. It describes the memory model of Java method execution: each method execution creates a Stack Frame to store information about local variables, operand stacks, dynamic links, method exits, etc. Each method from the call to the end of execution, corresponding to the process of a stack frame from the virtual machine stack to the stack.
  • Local variable table: stores basic types known at compile time (Boolean, byte, CHAR, short, int, float, long, double), object references (reference types), and returnAddress types (which refer to the address of a bytecode instruction)
  • Memory leak exception:

StackOverflowError: Stack depth of thread request is greater than the depth allowed by the virtual machine. OutOfMemoryError: If the vm stack can be dynamically expanded and sufficient memory cannot be allocated during the expansion.

3. Local method stack

  • It differs from the Java virtual machine stack in that the Java virtual machine stack performs Java methods (that is, bytecode) services for the virtual machine, whereas the Native method stack serves Native methods used by the virtual machine.
  • Memory leak exception:

StackOverflowError: Stack depth of thread request is greater than the depth allowed by the virtual machine. OutOfMemoryError: If the vm stack can be dynamically expanded and sufficient memory cannot be allocated during the expansion.

4. The Java heap

  • For most applications, this area is the largest chunk of memory managed by the JVM. Thread sharing, mainly to store object instances and arrays. All new instances are stored in the TLAB, which is allocated to multiple Thread private Allocation buffers (TLabs). It can be physically discontinuous, but logically continuous.
  • Memory leak exception:

OutOfMemoryError: Thrown if there is no memory in the heap to complete instance allocation and the heap can no longer be extended.

5. Methods area

  • It is a shared memory area that stores data such as class information, constants, static variables, and code compiled by the just-in-time compiler that has been loaded by the VIRTUAL machine.

6. Runtime constant pool

  • It is part of the method area and is used to hold various literal and symbolic references generated at compile time. Both the compiler and the runtime (intern() of String) can pool constants.
  • Memory leak exception:

OutOfMemoryError: An OutOfMemoryError is thrown when memory cannot be allocated.

7. Direct memory

  • NIO (New Input/Output) class was added in JDK 1.4, introducing an I/O method based on Channel and Buffer, which can use Native function library to allocate out-of-heap memory directly. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory. Can avoid time-consuming data operations back and forth between the Java heap and Native heap.
  • Memory leak exception:

OutOfMemoryError: Is limited by native memory and occurs when the sum of memory regions is greater than the physical memory limit, resulting in dynamic expansion.

2. Create and use a VM object

1. Object creation

When we use a new object, the operation for the JVM is not as simple as the code looks.

  • The JVM goes back and checks to see if the argument to this directive can locate a symbolic reference to a class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.
  • When the class load check passes, the JVM allocates memory space to the new object, and the amount of memory the object needs is fully determined after the class load is complete. There are two further cases of allocating memory in the JVM heap:

(1) a pointer collision type: if the Java heap memory is absolutely neat, all used memory in the heap aside and free memory on the other side, there is a pointer indicator as a cut-off point, the process of allocating memory is to move the pointer to the free space a and the object is equal to the size of the distance. (2) If the Java heap memory is not neat, but free and used memory are interleaved, there is no way to allocate memory using pointer collisions. Instead, the JVM must maintain a list of what memory is available, find enough memory to hold objects, allocate it to objects, and register it in the list.

  • When memory allocation is complete, the JVM initializes all allocated memory to zero (excluding object headers).
  • The JVM then makes the necessary Settings for the object, such as which instance of the class the object belongs to, the hash code of the object, and the GC generation age of the object, which are put in the object header.
  • For the JVM, a new object has been generated at this point, but for the Java program, the creation of the object has just begun, the init method has not been executed, and all fields are zero. The new instruction is followed by the init method, which initializes the object as desired by the programmer, so that a usable object is fully generated.

2. Memory layout of the object

In the JVM, objects are divided into three areas: Header, Instance Data, and Padding.

  • Object Header: contains two parts:

The first part is used to store the runtime data of the object itself, such as hash code, GC generation age, lock status flag, lock held by the thread, biased thread ID, biased timestamp, etc., 32 bits for 32-bit virtual machines, 64 bits for 64-bit virtual machines. It’s officially called the ‘Mark Word’. The second part is the type pointer, the metadata pointer that an object points to its class, which the virtual machine uses to determine which class the object is an instance of. In addition, if it is a Java array, there must be a piece of data in the object header that records the length of the array, because normal objects can be sized using Java object metadata, whereas array objects cannot.

  • Instance Data: The contents of various types of fields defined in program code (both inherited from parent classes and defined in subclasses).
  • Padding: Not necessarily required. Padding is used to make sure the object size is an integer multiple of a byte.

3. Access and locate objects

We know that creating a new object in Java generates a reference type and an instance object. Instance object: Stored in the heap note: When creating a new instance object, the JVM also loads the instance object Java class file and stores the instance object’s type information in the method area. As we will see later, when accessing the object, the type information is also accessed in the method area. The REFERENCE type in the JVM specification only defines a reference to an object, but does not define how the reference locates the object. Therefore, different virtual machines have different ways to access an object. There are two main ways to access an object: handle and direct pointer.

  • The handle way

When handle access is used, a chunk of memory will be allocated in the Java heap as the handle pool. Reference stores the handle address of the object, and the handle contains two specific address information of instance object data and type data.

  • Direct pointer mode

When using direct pointer access, the layout of Java heap objects must consider how to store information about accessing object type data, because reference stores the object address.

  • The advantages and disadvantages

The biggest advantage of using handles is that reference stores stable handle addresses. In object movement (GC), only the address of the instance data pointer is changed, and reference itself does not need to be modified. The biggest advantage of direct pointer access is that it is fast and saves the time cost of a pointer location. Handle methods are good if the object is frequently GC, and direct pointer access is good if the object is frequently GC.

3. Garbage collection and memory allocation policies

1. An overview of the

The three areas of the program counter, virtual machine stack, and local method stack live and die with the thread (because it is thread private), and the stack frames in the stack methodically perform the exit and exit operations as methods enter and exit. The Java heap and methods area is different, an interface of multiple implementation classes need memory may not be the same, a method of multiple branch need memory may also be different, we only know those objects in the program at runtime can create, this part of the memory allocation and recovery are dynamic, the payback period of waste concern is this part of the memory.

2. The object is dead when the memory is reclaimed during garbage collection

The only thing you need to do before you recycle is determine which objects are ‘dead’ and which are ‘alive’. How to judge is the more critical problem.

  • Reference counting method

Add a reference counter to the object with a value of +1 each time a place references the object. When the reference is invalid, the counter value is -1. An object with a value of 0 at any time is no longer usable. Reference counting is difficult to solve the problem of circular reference.

  • Accessibility analysis

Starting from a series of objects called “GC Roots”, search down from these nodes. The path searched is called the reference chain. When there is no reference chain from an object to GC Roots (i.e., GC Roots to object is unreachable), the object is proved to be unavailable. So again, how do you pick a GCRoots object? In the Java language, objects that can be GCRoots include: (1). Objects referenced in the virtual machine stack (the local variable area in the stack frame, also known as the local variable table). (2). The object referenced by the class static attribute in the method area. (3). Object referenced by constant in method area. (4). Objects referenced by JNI(Native method) in the local method stack. For the reachability analysis algorithm, the unreachable object is not necessarily dead. If an object is declared dead, it needs to go through at least two marking stages: 1. If there is no reference chain connected to GCRoots after the reachability analysis of the object, then the object will be marked for the first time and filtered. The filtering condition is whether it is necessary to finalize the object, if the Object does not overwrite the Finalize method or whether the Finalize method has been executed by virtual machine. It is not necessary to execute the Finalize method of the object, that is, the object will be recycled. On the other hand, if the Finalize method is overwritten by the object, and the Finalize method has not been executed, the object will be placed ina Finalizer thread called F-Queue, and then the Finalizer thread automatically created by the virtual machine will execute the Object, and the virtual machine does not need to wait for the finalize method to be executed. That is, the virtual machine is only responsible for creating the thread, and the other tasks are left to the thread. 2. Mark the object in f-queue for the second time. If the object saves itself in finalize method, that is, it is associated with the GCRoots reference chain, such as assigning this keyword to other variables, the object will be removed from the collection of “to be collected” at the second mark. That will be recycled. The following code shows how an object can save itself in the Finalize method. However, it can only save itself once, and the second time it will be reclaimed.

3. Four reference states

Prior to JDK1.2, the definition of a reference in Java was traditional: if the value stored in a reference type of data represented the starting address of another chunk of memory, that chunk of memory represented a reference. This definition is pure, but too narrow: an object can only be referenced or not referenced. We want to describe objects that can remain in memory when there is enough space; If memory space is too tight after garbage collection, these objects can be discarded. Many system cache functions fit this application scenario. After JDK1.2, Java expanded the concept of reference, and divided it into strong reference, soft reference, weak reference, and virtual reference. The strength of these four references decreases successively.

  • Strong reference

References such as “Object obj = new Object()” are common in code. As long as strong references exist, the garbage collector will never reclaim the referenced Object.

  • Soft references

Describe objects that are useful but not necessary. Before the system is about to run out of memory exceptions, these objects are listed in the recycle range for a second recycle. An out-of-memory exception is thrown if there is not enough memory for this collection. In Java, SoftReference indicates a SoftReference.

  • A weak reference

Describes non-required objects. Objects associated with weak references only survive until the next garbage collection, and when the garbage collector works, objects associated with only weak references are reclaimed regardless of whether there is currently enough memory. Class WeakReference in Java represents a WeakReference.

  • Phantom reference

The sole purpose of this reference is to receive a system notification when the object is collected by the collector. The object associated with the virtual reference has nothing to do with its lifetime. The Java class PhantomReference represents a virtual reference.

Garbage collection algorithm

1. Reference counting

  • Reference counting method is simple to implement, high efficiency, in most cases is a good algorithm. It is the application of reference counting method to analyze the survival of the object, adding a reference counter to the object, every time there is a reference to the object, the counter is increased by 1, when the reference is invalid, the counter is decreased by 1, when the counter value is 0, the object is no longer used. It is important to note that reference counting is difficult to solve the problem of circular references between objects, and reference counting is not currently used in mainstream Java virtual machines to manage memory.

2. Mark clearing algorithm

The algorithm is simple and can be divided into two stages: marking and clearing

  • Flag: Scanning starts from the Root collection (GC Root) and marks an object as alive as it reaches it.
  • Clear: To clear unmarked objects after the scan is complete.

One drawback of this algorithm is that it generates memory fragmentation. Clearing an object leaves an area of memory, and if larger objects need to be allocated later, there will be no contiguous memory available.

3. Mark sorting algorithm

In order to solve the memory fragmentation of the tag cleaning algorithm, it can be optimized as the tag cleaning algorithm.

  • Flag: Scanning starts from the Root collection (GC Root) and marks an object as alive as it reaches it.
  • Clear: To clear unmarked objects after the scan is complete.
  • Collation: After all memory has been cleared, the inventory objects are moved to collate so that the living object memory and free memory are all in one contiguous piece of memory.

Another problem with this algorithm is that it is expensive to move objects every time.

4. Replication algorithm

  • Memory is divided into two equal blocks, and memory is always allocated on one of the blocks.
  • When collecting, all living objects are marked.
  • Copy all living objects to another free block of memory.
  • Clear the used memory.

This algorithm typically uses space for time, and there is no need to sort out objects. The two areas are used alternately. The biggest problem is that space is wasted, and the utilization rate of memory is only 50%.

5. Generational recycling algorithm

Generally, the heap area is divided into old age and Cenozoic age, and there is a generation beyond the heap area called permanent generation. The old era is characterized by a small number of objects that need to be collected in each garbage collection, while the new generation is characterized by a large number of objects that need to be collected in each garbage collection. The two types have different characteristics, and different collection algorithms are selected based on their characteristics.

1. Recycling for the new generation

By default, the new generation area is divided into three zones in a 8:1:1 ratio: 8: Eden, 1: Survivor1, and 1: Survivor2. How to deal with it:

  • There is always a chunk of Survivor that is empty, making the memory usage 90%.
  • The program runs to allocate memory in Eden and one of the Survivor1 blocks.
  • When GC is executed, surviving objects are moved to the empty Survivor2.
  • Memory allocation is then continued in Eden and Survivor2, with Survivor1 left empty for next use.

This algorithm improves memory usage and avoids memory fragmentation. However, we need to consider the memory allocation ratio. If the memory of Survivor2 is insufficient during the first GC, the object will be placed in the old age region, and the allocation ratio can be adjusted reasonably to achieve better GC processing. It should be noted that if the Eden region allocation is too small, GC will occur frequently.

2. Old age recycling

  • Old objects are long-lived objects, so the survival rate will be high even after GC, so it is a good choice to use tag clearing or tag collation algorithm.

3. Permanent generation recycling

Used to store static files, such as Java classes, methods, etc. Persistent generation has no significant impact on garbage collection, but some applications may generate or call classes dynamically, such as Hibernate, etc. In such cases, a large persistent generation space needs to be set up to store the classes added during the run. Persistent generation is also called method region.

5. The usual garbage collector

The garbage collector is an application of the garbage collection algorithm.

1.Serial collector (replication algorithm)

Features:

  • Collection for the New Generation
  • Copy algorithm is adopted;
  • Single-thread collection;
  • When garbage collection is done, all worker threads must be paused until complete;
  • Simple and efficient.

Application Scenarios:

  • It is still the default new generation collector for HotSpot in Client mode.
  • Simple and efficient (compared to the single-threaded of other collectors);
  • For environments limited to a single CPU, the Serial collector achieves the highest single-thread collection efficiency without thread interaction (switching) overhead;
  • In a user’s desktop application scenario, the available memory is generally small (tens of megabytes to one or two hundred megabytes) and garbage collection can be completed in a relatively short time (tens of MS to more than one hundred MS), as long as it does not occur frequently, this is acceptable.

2.ParNew collector (copy algorithm)

The ParNew garbage collector is a multithreaded version of the Serial collector. Features:

  • With the exception of multithreading, the behavior and characteristics of the Serial collector are the same.

Application Scenarios:

  • In Server mode, the ParNew collector is a very important collector because it is currently the only one besides Serial that works with the CMS collector;
  • However, in a single CPU environment, it is no better than the Serail collector because of the thread interaction overhead.

6. Parallel Avenge

The Parallel Collector is also known as a Throughput Collector because of its affinity to the Throughput. Features:

  • Cenozoic collector;
  • Copy algorithm is adopted;
  • Multithreaded collection;
  • Collectors such as CMS focus on minimizing the pause time of user threads during garbage collection; The goal of the Parallel Insane is to achieve a controlled Throughput.

Application Scenarios:

  • The goal of high throughput is to reduce garbage collection time and allow user code to run longer;
  • When the application runs on multiple cpus and does not have a particularly high pause time requirement, that is, the program mainly performs calculations in the background without much interaction with the user; For example, applications that perform batch processing, order processing, payroll, scientific calculations;

Ps: Throughput and collector concerns specification

  • Throughput

The ratio of CPU time spent running user code to total CPU consumption; Throughput = run user code time/(run user code time + garbage collection time); High throughput means less garbage collection time and longer runtime for user code;

  • Desired goals (concerns) of the garbage collector

Pause time: 1. The shorter the pause time is suitable for the program that needs to interact with the user; 2. Good response speed can improve user experience; Throughput: 1. High throughput can efficiently use THE CPU time to complete the computing task as soon as possible; 2. It is mainly suitable for tasks that do not need too much interaction in the background; 1. Reduce the memory space of the heap as much as possible while achieving the first two goals; 2. Better spatial locality can be obtained;

Serial Old collector (mark-collation algorithm)

Serial Old is an older version of the Serial collector. Features:

  • For the old age;
  • “Mark-collation” algorithm is adopted.
  • Single-thread collection;

Application scenarios

  • It is mainly used in Client mode.
  • In Server mode there are two main uses:

To be used with the Parallel Collector insane or earlier. 2. As a backup plan for CMS collector, used in the event of Concurrent Mode Failure of Concurrent collection;

5.Parallel Old collector (Mark-collation)

The Parallel Old garbage collector is an older version of the Parallel Insane collector. Features:

  • For the old age;
  • “Mark-collation” algorithm is adopted.
  • Multithreaded collection;

Application Scenarios:

  • JDK1.6 and later used to replace the Serial Old collector;
  • Especially in Server mode with multiple cpus; The Parallel Insane plus the Parallel Old collector is the result of the throughput and CPU-sensitive applications.

CMS collector (mark-clean algorithm)

Concurrent Mark Sweep (CMS) collectors are also known as Concurrent Low Pause collectors or low-latency garbage collectors. The characteristics of

  • For the old age;
  • Based on the “mark-clean” algorithm (no compression operation, memory fragmentation);
  • To obtain the shortest recovery pause time as the goal;
  • Concurrent collection, low pause;
  • Need more memory;
  • HotSpot is the first truly Concurrent collector in JDK1.5. For the first time, garbage collection threads work (basically) at the same time as user threads;

Application Scenarios:

  • Scenarios with a lot of user interaction;
  • Expect the system to stop the shortest time, pay attention to service response speed;
  • To give users a better experience, such as the common WEB, B/S system on the server application;

6. JVM class loading mechanism

1. An overview of the

The virtual machine loads the data describing the Class from the Class file into memory, verifies, parses, and initializes the data, and eventually forms Java types that the virtual machine can use directly.

2. Class loading timing

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) :

  • 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.
  • When a reflection call is made to a class using the methods of the java.lang.Reflect package.
  • When initializing a class, if the parent class is not initialized, the initialization of the parent class is triggered first.
  • 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.
  • 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.

3. Class loading process

1. The load

  • Gets the binary byte stream that defines a class by its fully qualified name
  • Transform the static storage structure represented by this byte stream into the runtime data structure 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.

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

  • If the component type of the array is a reference type, it is recursively class-loaded.
  • If the component type of the array is not a reference type, the Java virtual machine marks the array for bootstrap classloader association.
  • 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.

How to load a. Class file

  • Load directly from the local system
  • Download the. Class file from the network
  • Load. Class files from zip, JAR, etc archives
  • Extract. Class files from a proprietary database
  • Dynamically compile Java source files into.class files

2. Verify

Is the first step in connecting and ensures that the byte stream in the Class file contains the information required by the current VIRTUAL machine.

  • File format validation

1. Check whether the version starts with magic number 0xCAFEBABE 2. Check whether the major and minor versions are within the processing range of the current VM 3. Whether the constants in the constant pool have types that are not supported constants (check the constant tag flag) 4. 5. Constant of type CONSTANT_Utf8_info is there any data that does not conform to UTF8 encoding. 6 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 class (other than java.lang.object) 2. Whether the parent of this class inherits from a class that is not allowed to be inherited (final modified classes) 3. If the class is not abstract, does it implement all methods required in its parent class or interface 4? Whether the fields and methods in the class are in conflict with the parent class (overwriting the final fields of the parent class, and the occurrence of non-standard overloading) is mainly the semantic verification of the metadata information of the class to ensure that there is no metadata information that does not conform to the Java language specifications.

  • Bytecode verification

1. Ensure that the data type of operand stack and the sequence of instruction code work together at any time (no int will be read as long) 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 for subclass objects to be assigned to superclass data types, 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 the corresponding class 2 can be found for fully qualified names described by character creation in symbolic references. Whether a field descriptor for a character method exists in the specified class and the method and field 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.

3. Prepare

This phase formally allocates memory for the class and sets initial values for class variables, which are allocated in the method area (variables with static modifiers do not include instance variables). Note that:

  • Only static variables that are static are allocated and assigned default values (such as 0, 0L, NULL, false, etc.).
  • Final static literal constants are assigned initial values directly (initial values are not assigned default values; if they are not literal static constants, they are assigned default values just like static variables).

public static int value = 10; 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 10 is stored in the clinit() method after the program is compiled, so value is assigned during initialization.

4. The parsing

This stage is where the virtual machine replaces symbolic references in the constant pool with direct references.

  • A symbolic reference is a set of symbols that describe a target, which can be any literal. Concepts that are part of compilation principles include fully qualified names including classes and interfaces, field names and descriptors, and method names and descriptors.
  • A direct reference is a pointer to a target directly, a relative offset, or a handle to the target indirectly. Such as a pointer to a class in the method area.
  • Assume that a class has a static variable of a custom type. After parsing, the static variable will be a pointer to the class’s memory address in the method area

5. The initialization

1. There are two ways to assign initial value:

  • Specify an initial value when defining a static variable. Private static String x=”123″;
  • Assign values to static variables in static code blocks. Such as the static {x = “123”; }

Note: Only active use of a class causes initialization of the class.

2. Clinit and init

When the class file is compiled, the compiler generates two methods added to the class file: clinit, the class initialization method, and init, the instance initialization method.

  • clinit

Clinit refers to a class constructor that performs static variable initialization and static block execution during the initialization phase of the class loading process. 1. Clinit methods will not be generated if there are no static variables or blocks of code in the class. 2. When executing the Clinit method, the parent class’s Clinit method must be executed first. 3. The Clinit method is executed only once. 4. The order in which static variable assignments and static code blocks are merged is determined by the order in which they appear in the source file.

  • init

Init refers to an instance constructor that is executed during class instantiation, including initialization of member variables and execution of code blocks. 1. Init method will not be generated if there are no member variables and code blocks in the class. 2. Before executing the init method, you must first execute the init method of the parent class. 3. Init is executed every time it is instantiated. 4. Init allocates memory for instance variables, assigns default values, and then assigns initial values or code blocks according to the order in the source code

6. Uninstall

  • The system.exit () method is executed
  • The program completes normally
  • The program encounters an exception or error during execution and terminates abnormally
  • The Java virtual machine process was terminated due to an operating system error. Procedure

7. Parental delegation model

From the perspective of Java virtual machines, there are only two different class loaders: one is the Bootstrap ClassLoader, which is implemented in C++ language and is part of the virtual machine itself; The other is all the other class loaders that are implemented in the Java language, independent of the virtual machine, and all inherit from the Java.lang.ClassLoader. From the Java developer’s point of view, the class loaders can be divided more carefully. Most Java programs use one of three system-provided classloaders.

  • Bootstrap ClassLoader: This class handler is responsible for storing it in the JAVA_HOME\lib directory, or in the path specified by the -xbootCLASspath parameter, and is recognized by the virtual machine (only by the file name, such as rt.jar, Libraries with incorrect names will not be loaded even if placed in the lib directory.) Libraries are loaded into the virtual machine memory. The boot class loader cannot be directly referenced by Java programs. If you need to delegate the loading request to the boot class loader when writing a custom class loader, you can use NULL instead.
  • Extension ClassLoader: This loader is implemented by sun.misc.Launcher$ExtClassLoader, which loads all libraries in the < JAVA_HOME > \lib\ext directory, or in the path specified by the java.ext.dirs system variable. Developers can use the extended classloader directly.
  • Application ClassLoader: This ClassLoader is implemented by sun.misc.Launcher $app-classloader. Since this ClassLoader is the return value of the getSystemClassLoader () method in ClassLoader, it is also commonly referred to as the system ClassLoader. It is responsible for loading the libraries specified on the user’s ClassPath. Developers can use this class loader directly, and this is generally the default class loader if the application does not have its own custom class loader.

The working process of the parental delegation model is: If a class loader received the request of the class loading, it won’t try to load the first class, but when Fred loader to delegate the request to complete, each level of class loading, so all the class loading request should be transferred to the top floor to start the class loader, only when the parent feedback they can’t load this request, The subclass loader will try to load it itself. Advantages of parental delegation:

  • The advantage of parental delegation is that Java classes have a hierarchy of priorities with their classloaders. This hierarchy avoids reloading classes, and there is no need for the child ClassLoader to load the class again when the parent has already loaded the class.
  • Second, for security reasons, defined types in the Java core API will not be arbitrarily replaced. Suppose that a class named java.lang.Integer is passed over the network through the parent delegate mode to the initiator class loader, and the initiator class loader finds the class with this name in the core Java API and finds that the class has been loaded. Instead of reloading java.lang.Integer passed by the network, integer.class is returned, which prevents the core API library from being tampered with.
  • You might think that if we had a custom class named java.lang.SingleInterge in the classpath path, which does not exist in java.lang and is passed through parent delegate mode to the boot class loader, it would not be loaded because there is no class in the parent class loader path. Delegate the reverse to the subclass loader, which eventually loads the class through the system class loader. But it is not allowed to do so, because the Java. Lang is the core API package, and need to access, forced load will quote us the Java. Lang. SecurityException: Prohibited package name: Java. Lang anomalies.