JVM knowledge system integration

Original link: https://reiner.host/posts/d137c087.html

foreword

The information on the Internet is relatively complex, and there is little systematic information. Therefore, I collected the information and made some integration according to my own understanding. This article is for self-understanding and summary, and does not represent a standard answer.

start with hello world

java starts by writing ‘System.out.println(“hello world”)’, and compiles and runs, what happened during this time.

The whole process of .java files from compilation to completion (class loading process)

The complete cycle of a .java file is that java is encoded into a .class file that can be recognized by jvm, and then the general process is: load –> connect –> initialize –> use –> unload

1. Loading process

1. Obtain the binary byte stream that defines this class through the full class name (similar to reflection)
2. Convert the static storage structure represented by the byte stream into the runtime data structure of the JVM method area
3. Generate a java.lang.Class object representing the class in memory as the access entry for these data in the method area (so that the code can access the object through the full class name)
PS: The array type is not created by the class loader. It is created directly by the JAVA virtual machine. The loading of the array can be controlled by the custom class loader.

1.1 The class loader required during the loading process

There are three class loaders in the JVM, except BootstrapClassLoader, other class loaders are implemented by Java and all inherit from java.lang.ClassLoader

1. BootstrapClassLoader: The top-level loading class, implemented by C++, is responsible for loading jar packages and classes in the %JAVA_HOME%/lib directory or all classes in the path specified by the -Xbootclasspath parameter.
2. ExtensionClassLoader: Mainly responsible for loading jar packages and classes in the %JRE_HOME%/lib/ext directory, or jar packages in the path specified by the java.ext.dirs system variable.
3. AppClassLoader (application class loader): a loader for our users, responsible for loading all jar packages and classes under the current application classpath.

1.2 Model design of class loader (parent delegation model)

Each class has a class loader corresponding to it. When loading a class, the system will first determine whether the class has been loaded. If it is loaded, it will return directly. Otherwise, it will try to load. When loading, the parent class’s loadClass will be called first. () method, when the parent class loader cannot handle it, it is handled by itself.

For example: Custom Loader (judging whether the class has been loaded or not, and entrusting the superior processing) –> AppClassLoader (application class loader, also judge whether it has been loaded, and entrusting the superior processing if it is not loaded) –> ExtensionClassLoader –> BootstrapClassLoader

The whole process is to pass up one by one, (if the superior cannot handle it), and then pass it down one by one

benefit:
1. The parent delegation model ensures the stable operation of Java programs and avoids repeated loading of classes (the way the JVM distinguishes different classes is not only based on the class name, the same class file is loaded by different class loaders, resulting in two different classes kind)
2. Ensure that the core API of Java is not tampered with. If the parent delegation model is not used, but each class loader loads itself, there will be some problems. For example, if we write a class called java.lang.Object, then when the program runs, the system will have many different Object class (that is, the system cannot distinguish whether it is the Object object that comes with jdk or the Object object created by the user).

Custom class loader: inherit from ClassLoader

2. Class loading verification process

1. File format verification, verify whether it conforms to the class file specification, whether the version number is supported, and whether the constants in the constant pool have unsupported types
2. Metadata verification, analyzing the semantics of the bytecode to save its compliance with the requirements of the java language specification, such as: whether this class has a parent class (except java.langObject), whether it inherits the class modified by final, and so on.
3. Bytecode verification, a more complex stage, will verify the method body logic of the class, such as whether the type conversion is valid, the bytecode instruction jump exception, etc.
4. Symbolic reference verification, verifying whether the corresponding class is found in the symbolic reference, whether the class permission can be referenced, etc.
Summary: Verify that the compiled code is legal and can run normally

3. Class loading preparation

The preparation stage is the stage of formally allocating memory for the class variable and setting the initial value of the class variable. * At this time, only the class variable (static variable) is allocated for memory allocation. Here, the initialized variable value is the zero value of the data type, not the actual value. If it is final modification, assign the actual value directly

4. Analysis phase

The process of replacing symbolic references in the variable pool in the Java virtual machine with direct references during the parsing phase. Simply put, it is to convert the class name qualification into a Class object reference in actual memory.
The JAVA virtual machine prepares a method table for each class to store the address of the method. When you need to call a class, you only need to know the location of the method. By parsing the symbol reference, it can be directly converted to the target method. Summary of the location of the method table in the class: java obtains the class object through the full class name, and through the parsing operation

5. Initialization Phase

The initialization phase is the process of executing the initialization method () method, which is automatically generated after compilation.

1. Initialize a class. If its parent class has not been initialized, trigger the initialization of the parent class first.
2. Only when you actively use the class will the class be initialized (that is, when the NEW object)
3. When the virtual machine starts, the Main method class will be initialized first.
4.  

6. How memory is allocated

How to allocate memory when the class is loaded?

The virtual machine starts to load the class and allocate memory when the new object instruction is executed. The process is: class loading check –> determine whether the class is loaded (if the class is not loaded, load the class first) –> the class is loaded, start to allocate memory – > Execute initialization -> set object header -> execute init method.

6.1. Class loading checks

When actively using a class (new an object), first check whether the parameters of this instruction can locate a symbolic reference of a class in the constant pool, and check whether the class represented by this symbolic reference has been loaded, resolved and initialized. (that is, to check if the class has already been loaded). If not, the corresponding class loading process must be executed first.

6.2. Start allocating memory

If it has not been loaded, after the class loading check is passed, the virtual machine will allocate memory for the new object. There are two allocation methods: “pointer collision” and “free list”. Which allocation method is selected depends on whether the Java heap is regular or not. Whether the Java heap is regular or not is determined by whether the garbage collector used has compaction.

  • Pointer collision:

    • Applicable occasion: When the heap memory is regular (that is, there is no memory fragmentation).
    • Principle: All the used memory is integrated on one side, the unused memory is placed on the other side, and there is a demarcation pointer in the middle, and it is only necessary to move the pointer to the size of the object memory in the direction of the unused memory.
    • GC collectors using this allocation method: Serial, ParNew
  • Free list:

    • Applicable occasions: When the heap memory is irregular.
    • Principle: The virtual machine maintains a list, which records which memory blocks are available. When allocating, find a large enough memory block to divide it into object instances, and finally update the list records.
    • GC collector using this allocation method: CMS

Which one of the above two methods to choose depends on whether the Java heap memory is regular or not. Whether the Java heap memory is regular depends on whether the GC collector’s algorithm is “mark-sweep” or “mark-clean” (also known as “mark-compress”). It is worth noting that the copy algorithm memory is also regular.

PS: The default object is allocated in the Eden area, and the large object is directly allocated in the old age

Memory allocation concurrency problem

The virtual machine uses two ways to ensure thread safety:

  • CAS + retry on failure: CAS is an implementation of optimistic locking. The so-called optimistic locking is to complete an operation without locking each time but assuming that there is no conflict. If it fails due to a conflict, it will retry until it succeeds. The virtual machine uses CAS coupled with failed retry to ensure the atomicity of update operations.
  • TLAB: Pre-allocate a piece of memory in the Eden area for each thread. When the JVM allocates memory to the objects in the thread, it first allocates it in the TLAB. When the object is larger than the remaining memory in the TLAB or the memory of the TLAB is exhausted, the above method is used again. CAS for memory allocation

That is to say, each thread will pre-allocate a piece of memory in the Eden area of ​​the heap for the object to use, and when it is not enough, it will use optimistic lock competition allocation to ensure the atomicity of the operation.

6.3. Initializing a zero value

After the memory allocation is completed, the virtual machine needs to initialize the allocated memory space to a zero value (excluding the object header). This step ensures that the instance field of the object can be used directly in the Java code without assigning an initial value, and the program can Access to the zero value corresponding to the data type of these fields.

6.4. Setting the object header

After initializing the zero value, the virtual machine needs to make necessary settings for the object, such as which class instance the object is, how to find the metadata information of the class, the hash code of the object, and the GC generation age of the object. This information is stored in the object header. In addition, according to the current running state of the virtual machine, such as whether to enable the bias lock, etc., the object header will be set in different ways.

6.5. Execute the init method

After the above work is completed, from the perspective of the virtual machine, a new object has been created, but from the perspective of the Java program, the object creation has just started, the method has not been executed, and all fields are still zero. So in general, after executing the new instruction, the method will be executed, and the object will be initialized according to the programmer’s wishes, so that a truly usable object is completely generated.

6.6. Access positioning of objects

Creating an object is to use the object. Our Java program operates on the specific object on the heap through the reference data on the stack. The access method of objects is determined by the implementation of the virtual machine. At present, the mainstream access methods are: using handles and direct pointers.

  • If a handle is used, a piece of memory will be divided into a handle pool in the Java heap, and the handle address of the object is stored in the reference, and the handle contains the specific address information of the object instance data and the object type data.

  • Direct pointer If you use direct pointer access, the address stored in the reference is the address of the object.

Simply put, when we want to use a class, the JVM will obtain the object in these two ways. The advantage of using the handle is that there is a layer in the middle. When the object is moved, it will only change the instance data pointer in the handle, while the direct pointer The advantage is speed.

6.7. Escape Analysis

Under normal circumstances, new objects are allocated on the heap, but when certain conditions are met, they will be allocated on the stack first.

We know that FULL GC is triggered when heap space is low, and FULL GC can seriously affect performance.

Some objects are actually generated temporarily and are only used in a certain method. If these objects can be destroyed together with the pop-up of the stack, the pressure of garbage collection will be relieved.

In order to reduce the number of temporary objects allocated in the heap, the JVM determines whether the object will be accessed externally through escape analysis. If it does not escape, the object can be allocated memory on the stack. Destroyed when the stack frame is popped out of the stack, reducing the pressure on the GC.

What is escape analysis

When the created object is only used in a method, it is an escape object when it is not used by other classes. The following code:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 public class Test {

public User test1 () {
User user = new User();
user.setId( 1 );
user.setName( "AA" );
return user;
}

public void test2 () {
User user = new User();
user.setId( 2 );
user.setName( "BB" );
}
}

Since test1 returns a reference address, it is used externally, so it does not attribute an escape object, and the User in test is not used anywhere else, so it belongs to an escape object, and the base can be allocated in the stack.

How to turn on escape analysis

Escape analysis is enabled by default after JDK7

 1
2
 -XX:+DoEscapeAnalysis Enable escape analysis
-XX:-DoEscapeAnalysis turns off escape analysis
6.8. Scalar substitution

If an object can be determined by escape analysis, it can be allocated on the stack, but we know that the space of a thread stack is 1M by default, and the stack frame space is even smaller. Object allocation requires a continuous space. After calculation, if the object can be placed on the stack frame, but the space of the stack frame is not continuous,

For an object, this is not acceptable, because the object needs a contiguous piece of space. then what should we do? At this time, the JVM made an optimization. Even if there is no continuous space method in the stack frame, it can put the object in the stack frame by other methods. This method is scalar replacement.

Scalar replacement is not to put the entire User object into the stack frame, but to take out the member variables in User and place them in each free space. This is not to put a complete object, but to break up the object into member variables and put them on the stack frame. Of course, there will be a place to identify which object this property belongs to, which is scalar substitution.

 1
 -XX:+EliminateAllocations enable scalar substitution

It is enabled by default after JDK7.

6.9. Scalar Substitution and Aggregation

Scalar substitution and aggregation are definitions of variables or objects in escape analysis.

The basic types of JAVA belong to scalars, such as: int, long and other basic types, objects belong to the quantity that can be further decomposed, so they belong to the aggregate quantity

7. Uninstall

Uninstalling a class needs to meet 3 requirements:
1. All instance objects of this class have been GCed, which means that there are no instance objects of this class in the heap.
2. The class is not referenced anywhere else
3. The instance of the class loader of the class has been GCed

7.1. Under what circumstances will an object be GC (garbage collected)

Almost all object instances are placed in the heap. The first step before garbage collection of the heap is to determine which objects have died (that is, objects that can no longer be used in any way).

There are two algorithms for judging the death of an object: reference counting and reachability analysis.

  • reference counting

Add a reference counter to the object. Whenever there is a reference to it, the counter is incremented. When the reference is invalid, the counter is decremented by 1. The object whose counter is 0 at any time can no longer be used.

  • Reachability Analysis Algorithms

The basic idea of ​​this algorithm is to use a series of objects called “GC Roots” as the starting point, and start searching downward from these nodes. The path that the node travels is called the reference chain. When an object has no reference chain to the GC Roots If it is connected, it proves that the object is unavailable and needs to be recycled.

Which objects can be used as GC Roots?

Objects referenced in the virtual machine stack (local variable table in the stack frame) Objects referenced in the local method stack (Native method) Objects referenced in the method area of ​​the class static attributes Referenced by constants in the method area All objects held by synchronization locks Objects can be recycled, does that mean they will be recycled?

Even objects that are unreachable in the reachability analysis method are not “necessary to die”. At this time, they are temporarily in the “probation stage”. To truly declare an object dead, at least two marking processes are required; The unreachable object in the sex analysis method is marked and filtered for the first time, and the filtering condition is whether it is necessary to execute the finalize method for this object. When the object does not override the finalize method, or the finalize method has been called by the virtual machine, the virtual machine considers these two cases to be unnecessary.

Objects that are determined to be executed will be placed in a queue for a second mark, unless the object is associated with any object in the reference chain, otherwise it will be really recycled.

Summary of the algorithm for judging the death of an object

The reference counting method judges the object by simple counting, and the reachability analysis algorithm judges the object through the reference chain. The unreachable object will not necessarily be recycled. The object will be marked in a queue for the second time, unless the object is on the reference chain. Any one of the objects is associated with it, otherwise it will be really recycled.

Reference types in garbage collection

Whether judging the number of object references by reference counting method, or judging whether the reference chain of an object is reachable by reachability analysis method, judging the survival of an object is related to “reference”.

  • Strong Reference

The object that is directly new in the code is a strong reference, and the JVM GC will not reclaim it. When the memory space is insufficient, the Java virtual machine would rather throw an OOM exception than reclaim the object with a strong reference to release the memory.

  • Soft Reference

If there is enough memory space, the garbage collector will not reclaim it, if there is not enough memory space, the memory of these objects will be reclaimed. The object can be used by the program as long as it is not collected by the garbage collector. Soft references can be used to implement memory-sensitive caches.

Define a soft reference object:

 1
2
3
4
 Object o= new Object();
SoftReference<Object> reference= new SoftReference<>(o);
System.out.println(o);
System.out.println(reference.get());
  • Weak Reference (WeakReference)

Regardless of whether the memory is sufficient, as long as the GC weakly referenced objects must be reclaimed.

 1
2
3
4
 Object o= new Object();
WeakReference<Object> reference= new WeakReference<>(o);
System.out.println(o);
System.out.println(reference.get());
  • PhantomReference

“Virtual reference”, as the name suggests, is just in name only. Unlike other references, virtual reference does not determine the life cycle of an object. If an object only holds phantom references, then it can be garbage collected at any time as if it had no references at all.

Phantom references are mainly used to track the activity of objects being garbage collected.

One difference between phantom references and soft references and weak references is that phantom references must be used in conjunction with a reference queue (ReferenceQueue). When the garbage collector is ready to reclaim an object, if it finds that it still has a virtual reference, it will add the virtual reference to the reference queue associated with it before reclaiming the memory of the object. The program can know whether the referenced object is about to be garbage collected by judging whether a virtual reference has been added to the reference queue. If the program finds that a virtual reference has been added to the reference queue, it can take necessary action before the memory of the referenced object is reclaimed.

Pay special attention to the fact that weak references and virtual references are rarely used in program design, and soft references are often used. This is because soft references can speed up the recovery of garbage memory by the JVM, maintain the operating safety of the system, and prevent memory overflow. (OutOfMemory) and other problems.

Phantom references and reference queues

 1
2
3
4
5
6
7
 Object o= new Object();
ReferenceQueue<Object> queue= new ReferenceQueue();
PhantomReference<Object> reference= new PhantomReference<>(o,queue);
System.out.println(o);
System.out.println(reference.get());
System.out.println(queue.poll());

7.2. Garbage Collection Algorithms

Mark-Clear Algorithm The algorithm is divided into “mark” and “clear” phases: first, all objects that do not need to be reclaimed are marked, and all unmarked objects are uniformly reclaimed after the marking is completed. It is the most basic collection algorithm, and the subsequent algorithms are obtained by improving its shortcomings. There are two obvious problems with this garbage collection algorithm:

Efficiency problem Space problem (a lot of discontinuous fragments after mark clear)

Mark-Copy Algorithms In order to solve the efficiency problem, the “mark-copy” collection algorithm appeared. It can divide memory into two blocks of the same size and use one of them at a time. When the memory of this block is used up, the surviving objects are copied to another block, and then the used space is cleaned up again. In this way, each memory reclamation is to reclaim half of the memory range.

replication algorithm

The mark-cleaning algorithm is a marking algorithm proposed according to the characteristics of the old age. The marking process is still the same as the “mark-clean” algorithm, but the subsequent steps are not to directly recycle the recyclable objects, but to move all surviving objects to one end. Then directly clean up the memory outside the end boundary.

mark-collate algorithm

Generational Collection Algorithm The current generational collection algorithm is used in the garbage collection of virtual machines. This algorithm has no new ideas, but divides the memory into several blocks according to the life cycle of the object. Generally, the java heap is divided into the new generation and the old generation, so that we can choose the appropriate garbage collection algorithm according to the characteristics of each generation.

For example, in the new generation, a large number of objects will die in each collection, so the “mark-copy” algorithm can be selected, and each garbage collection can be completed with only a small amount of object copying cost. The survival probability of objects in the old age is relatively high, and there is no extra space to allocate it, so we must choose the “mark-sweep” or “mark-clean” algorithm for garbage collection.

7.3. Space Allocation Guarantee Mechanism

Before Minor GC occurs, the virtual machine checks whether the maximum available contiguous space in the old generation is greater than the total space of all objects in the young generation.

If it is greater than, then this Minor GC is safe

If it is less than, the virtual machine checks to see if the HandlePromotionFailure setting value allows guarantee failure. If HandlePromotionFailure=true, it will continue to check whether the maximum available continuous space in the old generation is greater than the average size of objects promoted to the old generation. If it is greater, try a Minor GC, but this Minor GC is still risky; If it is less than or HandlePromotionFailure=false, a Full GC will be performed instead.

The space allocation guarantee is to ensure that the old generation itself has remaining space for all objects in the young generation before the Minor GC.

7.4. The Garbage Collector

If the collection algorithm is the methodology of memory recycling, then the garbage collector is the specific implementation of memory recycling.

The JVM has many garbage collectors, each of which corresponds to different usage scenarios. The list of collectors is as follows:

  • Serial collector
  • ParNew collector
  • Parallel Scavenge Collector
  • Serial Old Collector
  • Parallel Old Collector
  • CMS collector
  • G1 collector
  • ZGC collector

The following is a detailed introduction of each garbage collector collected online:

Serial collector
The Serial collector is the most basic and oldest garbage collector. As you can see from the name, this collector is a single-threaded collector. Its “single-threaded” meaning not only means that it only uses one garbage collection thread to complete garbage collection work, but more importantly, it must suspend all other worker threads during garbage collection work (“Stop The World ”) until it collects.

The new generation adopts the mark-copy algorithm, and the old generation adopts the mark-collation algorithm.

Serial collector

The designers of the virtual machine certainly knew about the poor user experience that Stop The World brought, so in subsequent garbage collector designs the pause time was getting shorter and shorter (there are still pauses, and the process of finding the best garbage collector continues ).

But is the Serial collector any better than other garbage collectors? Of course it is, it’s simple and efficient (compared to the single thread of other collectors). Since the Serial collector has no thread interaction overhead, it can naturally achieve high single-threaded collection efficiency. The Serial collector is a good choice for virtual machines running in Client mode.

ParNew collector
The ParNew collector is actually a multithreaded version of the Serial collector. Except for the use of multithreading for garbage collection, the rest of the behavior (control parameters, collection algorithms, recycling strategies, etc.) is exactly the same as the Serial collector.

The new generation adopts the mark-copy algorithm, and the old generation adopts the mark-collation algorithm.

ParNew collector

It is the first choice for many virtual machines running in Server mode, except for the Serial collector, it only works with the CMS collector (the true concurrent collector, which will be introduced later).

Parallel and Concurrency Concepts Supplement:

Parallel (Parallel): Refers to multiple garbage collection threads working in parallel, but the user thread is still in a waiting state at this time.

Concurrent (Concurrent): Refers to the user thread and the garbage collection thread executing at the same time (but not necessarily in parallel, may be executed alternately), the user program continues to run, and the garbage collector runs on another CPU.

Parallel Scavenge Collector
The Parallel Scavenge collector is also a multithreaded collector that uses a mark-copy algorithm, and it looks almost identical to ParNew. So what’s so special about it?

-XX:+UseParallelGC

使用Parallel 收集器+ 老年代串行

-XX:+UseParallelOldGC

使用Parallel 收集器+ 老年代并行

The Parallel Scavenge collector focuses on throughput (efficient use of CPU). Garbage collectors such as CMS focus more on the pause time of user threads (improving user experience). Throughput is the ratio of the time spent running user code in the CPU to the total CPU time spent. The Parallel Scavenge collector provides many parameters for users to find the most suitable pause time or maximum throughput. If you don’t know much about the operation of the collector and it is difficult to optimize manually, use the Parallel Scavenge collector with the adaptive adjustment strategy to put the memory It is also a good choice to leave management optimization to the virtual machine.

The new generation adopts the mark-copy algorithm, and the old generation adopts the mark-collation algorithm.

Parallel Scavenge Collector

This is the JDK1.8 default collector

Use the java -XX:+PrintCommandLineFlags -version command to view

-XX:InitialHeapSize=262921408 -XX:MaxHeapSize=4206742528 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
java version “1.8.0_211”
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
JDK1.8 uses Parallel Scavenge + Parallel Old by default. If the -XX:+UseParallelGC parameter is specified, -XX:+UseParallelOldGC is specified by default. You can use -XX:-UseParallelOldGC to disable this function.

Serial Old Collector
An older version of the Serial collector, which is also a single-threaded collector. It has two main purposes: one is used in conjunction with the Parallel Scavenge collector in JDK1.5 and earlier, and the other is as a fallback for the CMS collector.

Parallel Old Collector
An older version of the Parallel Scavenge collector. Use multithreading and a “mark-and-sort” algorithm. Where throughput and CPU resources are important, Parallel Scavenge and Parallel Old collectors can be prioritized.

CMS collector
The CMS (Concurrent Mark Sweep) collector is a collector whose goal is to obtain the shortest collection pause time. It is very suitable for use in applications that focus on user experience.

The CMS (Concurrent Mark Sweep) collector is the first true concurrent collector of the HotSpot virtual machine, and it is the first time that the garbage collection thread and the user thread work (basically) at the same time.

As can be seen from the two words Mark Sweep in the name, the CMS collector is implemented by a “mark-sweep” algorithm, and its operation process is more complicated than the previous garbage collectors. The whole process is divided into four steps:

Initial mark: suspend all other threads and record the objects directly connected to root, which is very fast;
Concurrent marking: Open GC and user threads at the same time, and use a closure structure to record reachable objects. But at the end of this phase, the closure structure is not guaranteed to contain all currently reachable objects. Because the user thread may continuously update the reference field, the GC thread cannot guarantee the real-time performance of the reachability analysis. So this algorithm will keep track of where these reference updates occur.
Re-marking: The re-marking phase is to correct the marking records of the part of the objects whose markings are changed because the user program continues to run during the concurrent marking period. The pause time in this phase is generally slightly longer than the initial marking phase, which is much longer than the concurrent marking phase. The marking phase is short and concurrent clearing: Start the user thread, and at the same time the GC thread starts to clean the unmarked area.
CMS garbage collector

From its name, it can be seen that it is an excellent garbage collector, the main advantages: concurrent collection, low pause. But it has the following three obvious disadvantages:

Sensitive to CPU resources;
Cannot handle floating garbage;
The recycling algorithm it uses – the “mark-and-sweep” algorithm results in a large amount of space fragmentation at the end of the collection.
G1 collector
G1 (Garbage-First) is a server-oriented garbage collector, mainly for machines with multiple processors and large-capacity memory. While meeting the GC pause time requirements with a high probability, it also has high-throughput performance characteristics.

Considered an important evolutionary feature of the HotSpot virtual machine in JDK1.7. It has the following characteristics:

Parallelism and Concurrency: G1 can make full use of the hardware advantages of CPU and multi-core environment, and use multiple CPUs (CPU or CPU core) to shorten Stop-The-World pause time. Some other collectors originally need to suspend the GC action executed by the Java thread, and the G1 collector can still allow the Java program to continue executing in a concurrent manner.
Generational collection: Although G1 can independently manage the entire GC heap without the cooperation of other collectors, it still retains the concept of generation.
Spatial integration: Different from CMS’s “mark-clean” algorithm, G1 is a collector based on the “mark-clean” algorithm as a whole; locally, it is based on the “mark-copy” algorithm.
Predictable pause: This is another big advantage of G1 over CMS. Reducing pause time is a common concern of G1 and CMS, but in addition to pursuing low pause, G1 can also establish a predictable pause time model, which allows users to use are specified explicitly within a time slice of length M milliseconds.
The operation of the G1 collector is roughly divided into the following steps:

Initial Mark Concurrent Mark Final Mark Filter Recycle
The G1 collector maintains a priority list in the background. Each time, according to the allowed collection time, the Region with the largest recovery value is preferentially selected (this is the origin of its name Garbage-First). This use of Region to divide the memory space and prioritized area recycling method ensures that the G1 collector can collect as much efficiency as possible within a limited time (the memory will be divided into zero).

The ZGC collector is similar to ParNew and G1 in CMS. ZGC also uses a mark-copy algorithm, but ZGC has made significant improvements to this algorithm.

There will be less Stop The World in ZGC!

Summarize

The overall process is as follows:
The programmer writes JAVA code, saves it as a .java file –> JDK then compiles the java file into a .class file –> virtual machine loads the .class file –> JVM executes the class loader (refer to the above class loading process, when a new object is created Triggered) –> After the class is loaded, it will start to allocate memory (the Main method class will be initialized when the virtual machine starts) –>

After the object memory is allocated, execute the init method (execute the constructor) -> but the object may be recycled when it is not referenced (depending on the recycling algorithm) -> unload (provided that the conditions are met).

This article is reproduced from: https://reiner.host/posts/d137c087.html
This site is for inclusion only, and the copyright belongs to the original author.