1: What is the JVM

The JVM, short for Java Virtual Machine, is a specification for computing devices. The JVM is an imaginary computer that is implemented by emulating various computer functions on an actual computer. The Java virtual machine consists of a set of bytecode instructions, a set of registers, a stack, a garbage collection heap, and a storage method field. The JVM shields platform-specific information, allowing Java programs to run unmodified on multiple platforms by generating object code (bytecode) that runs on the Java VIRTUAL machine. When the JVM executes bytecodes, it actually ends up interpreting bytecodes as platform-specific machine instructions.


What is the relationship between JRE/JDK/JVM

JRE(JavaRuntimeEnvironment) is the Java platform. All Java programs must run under JRE. Common users only need to run the developed Java program and install the JRE.

The Java Development Kit (JDK) is a Development Kit used by program developers to compile and debug Java programs. JDK tools are also Java programs that require JRE to run. To maintain JDK independence and integrity, the JRE is also part of the JDK installation. Therefore, in the JDK installation directory, there is a directory named JRE to store the JRE file.

The JVM(JavaVirtualMachine) is part of the JRE. It is an imaginary computer by simulating various computer functions on an actual computer. The JVM has its own complete hardware architecture, such as processors, stacks, registers, and the corresponding instruction system. The most important feature of the Java language is that it runs across platforms. The PURPOSE of using the JVM is to enable cross-platform implementation independent of the operating system.


3: Principle of JVM

The JVM is the core and foundation of Java, the virtual processor between the Java compiler and the OS platform. It is an abstract computer based on the underlying operating system and hardware platform, which can execute Java bytecode programs.

The Java compiler generates code or bytecode files that the JVM can understand, as long as it is oriented to the JVM. Java source files are encoded into bytecode programs that translate each instruction into a different platform machine code through the JVM and run on a specific platform.


4: Architecture of the JVM

ClassLoader (used to load. Class files)

Execution engine (execute bytecode, or execute local methods)

Runtime data area (method area, heap, Java stack, PC register, local method stack)


5: JVM runtime data area

First block: PC register

The PC register is used to store the JVM instructions that each thread will execute next. If this method is native, no information is stored in the PC register.

Block 2: JVM stack

The JVM stack is thread private. Each thread is created with the JVM stack, which holds variables of the local primitive types in the current thread. Boolean, char, byte, short, int, long, float, double), partial return results, and Stack frames. Objects of non-basic types only hold one address on the JVM Stack that points to the heap.

Block 3: Heap

It is the area where the JVM stores object instances as well as array values, and it can be considered that memory for all objects created by New in Java is allocated there, while memory for objects in Heap is waiting for GC to collect.

(1) The heap is shared by all threads in the JVM, so the allocation of object memory on it needs to be locked, which also leads to the relatively high overhead of new objects

(2) In order to improve the efficiency of object memory Allocation, Sun Hotspot JVM will allocate an independent space TLAB (Thread Local Allocation Buffer) for the created threads. The size of TLAB is calculated by THE JVM according to the running situation. There is no lock required to allocate objects on TLAB, so the JVM tries to allocate memory on TLAB when allocating objects on thread. In this case, the PERFORMANCE of allocating object memory in JVM is almost as efficient as that of C, but if the object is too large, it still uses heap space allocation directly

(3) TLAB only applies to Eden Space of the new generation, so when Java programs are written, it is usually more efficient to allocate multiple small objects than large objects.

(4) All newly created objects will be stored in the new Generation of Yong Generation. If data from the Young Generation survives one or more GCS, it will be transferred to the OldGeneration. New objects are always created in Eden Space.

Section 4: Method Area

(1) in the Sun JDK, this area corresponds to PermanetGeneration, also known as persistent generation.

(2) The method area stores the information of the loaded Class (name, modifiers, etc.), static variables in the Class, constant defined as final type in the Class, Field information in the Class, and method information in the Class. When the developer obtains the information through getName, isInterface and other methods in the Class object in the program, This data comes from the method region, which is also globally shared and is GC under certain conditions. An OutOfMemory error message is raised when the method region needs more memory than it allows.

Runtime Constant Pool

Fixed constants, references to methods and fields are stored in the class, and space is allocated from the method area.

Native Method Stacks

The JVM supports execution of native methods with a native method stack, an area used to store the state of each native method call.


6: Determination algorithm of object “dead”

Because program counters, The Java virtual machine stack, and the local method stack are thread proprietary, the memory they occupy is also created with the thread and reclaimed with the thread’s termination. The Java heap and method areas, on the other hand, are shared by threads and are the focus of GC.

With almost all objects in the heap, you need to consider which objects are still alive to recycle and which are dead to recycle before GC.

There are two algorithms to determine whether an object is alive or not:

1.) Reference counting algorithm: add a reference counter to an object. Whenever an object is applied, the counter is incremented by 1; When a reference is invalid, the counter decays by 1; A counter of 0 indicates that the object is dead and recyclable. However, it is difficult to solve the situation where two objects are referred to each other in a loop.

2.) Reachable analysis algorithm: a series of objects called “GC Roots” are used as the starting point to search downward from these nodes. The search path is called reference chain. Objects that can be used as GC Roots in Java include: objects referenced in the virtual machine stack, objects referenced by Native methods in the local method stack, objects referenced by static attributes in the method area, and objects referenced by constants in the method area.

In the mainstream implementations of major commercial programming languages, such as our Java, reachability analysis algorithms are used to determine whether objects are alive or not.


7: JVM garbage collection

Basic principle of Garbage Collection (GC) : Memory object is no longer used in recycling, for recycling in the GC method known as collector, because the GC need to consume some resource and time, Java in through analysis of the characteristics of the object’s lifecycle, according to the new and old generation way to collect object, by as much as possible to shorten the GC pause for application

(1) The collection of objects of the new generation is called minor GC;

(2) Collection of old generation objects is called Full GC;

(3) The program actively calls system.gc () to force the gc to be Full GC.

Different types of object references are collected in different ways by GC. References to JVM objects fall into four types:

(1) Strong references: By default, objects are strongly referenced (instances of this object are not referenced by other objects, and will only be recycled during GC).

(2) Soft references: Soft references are an application provided in Java that is suitable for caching scenarios (GC only when memory is low).

(3) Weak references: must be collected by the GC

(4) Virtual references: Since virtual references are only used to tell if an object is GC


8: Garbage collection algorithm

1. Mark-clear algorithm

The most basic algorithm is divided into two stages: mark the objects that need to be recovered, and uniformly recover all marked objects after the completion of marking.

It has two drawbacks: an efficiency problem, in that both the tagging and cleaning processes are inefficient; One is the space problem. After the mark is cleared, there will be a large amount of discontinuous memory fragmentation (similar to the disk fragmentation of our computer). The space fragmentation is so large that when large objects need to be allocated, they cannot find enough contiguous memory and have to trigger another garbage collection action in advance.


2. Replication algorithm

To solve the efficiency problem, the “copy” algorithm was developed, which divided the available memory into two equal chunks by capacity, and used only one of them at a time. When a block of memory is used up, the surviving objects are copied onto the other block, and the newly used memory space is cleaned up again. This solves the memory fragmentation problem, but at the cost of being able to reduce it by half with content.


3. Mark-tidy algorithm

The replication algorithm will carry out frequent replication operations when the object survival rate is high, and the efficiency will be reduced. Hence the mark-clean algorithm, which is the same as the mark-clean algorithm, but instead of cleaning up the object directly, all surviving objects are moved sideways and the memory beyond the end boundary is cleaned up.


4. Generational collection algorithm

The current GC of commercial virtual machines adopts generational collection algorithm, which has no new idea, but divides the heap according to the different life cycle of objects into: The new generation and the old generation, the method area is called permanent generation (the permanent generation has been deprecated in the new version, introducing the concept of meta-space, which uses JVM memory while meta-space directly uses physical memory).

This allows different collection algorithms to be used according to the characteristics of each generation.

Objects in the new generation “live and die overnight”, a large number of objects will die and a small number of objects will survive each GC, and the replication algorithm is used. The new generation is divided into Eden region and Survivor region (Survivor from and Survivor to), and the default size ratio is 8:1:1.

Objects in the old age use mark-clean or mark-tidy algorithms because they have a high object survival rate and no extra space to allocate guarantees.

When Eden is full, use Survivor from. When Survivor from is also full, perform Minor GC. Copy Survivor from Eden and Survivor from into Survivor to empty Eden and Survivor from, at which point the original Survivor from becomes the new Survivor to. The old Survivor to became the new Survivor from. When copying, if Survivor to cannot accommodate all the surviving objects, the object is copied into the old age according to the old age’s allocation guarantee (similar to a bank’s loan guarantee). If the old age cannot accommodate either, Full GC (old age GC) is performed.


Large objects directly into old age: a parameter in the JVM configuration – XX: PretenureSizeThreshold, make more than the set value of object directly into old age, the purpose is to avoid in Eden and Survivor area between a lot of memory copy.

Long-lived objects go old: The JVM defines an object age counter for each object, and if the object is still alive after Eden’s birth and passes through the first Minor GC and can be contained by Survivor, it will be moved to Survivor with an age of 1. If he/she has not survived a Minor GC, his/her age is increased by 1, and when he/she reaches a certain age (15 by default, which can be set with XX:MaxTenuringThreshold), he/she moves to the old age. However, the JVM does not always require a maximum age to advance to the old age. If the sum of all object sizes in the Survivor space of the same age (such as age X) is greater than half of Survivor, all objects older than or equal to x enter the old age directly without waiting for the maximum age requirement.


9: garbage collector

The garbage collection algorithm is the methodology and the garbage collector is the implementation. The JVM specification has no rules about how the garbage collector should be implemented, so the garbage collector is provided by different vendors and different versions of virtual machines, so let’s just look at HotSpot virtual machines.

After JDK7/8, all collectors and combinations of HotSpot virtual machine (wired) are as follows:


1. The Serial collector

The Serial collector, the most basic and oldest, was the only option for the next generation of mobile phones. It is single-threaded, uses only one CPU or one collection thread to complete garbage collection, and must “Stop the World” by suspending all other worker threads while it collects. Stopping all user threads is unacceptable for many applications. For example, when you are doing something and are forced to stop by others, can you still count the “alpacas” rushing through your mind?

Nevertheless, it is still the default new generation collector for virtual machine running in client mode: simple and efficient (compared to the single thread of other collectors, because there is no overhead of thread switching, etc.).

Working diagram:


2. ParNew collector

The ParNew collector is a multithreaded version of the Serial collector and behaves the same as the Serial collector (collection algorithms, stop the world, object allocation rules, collection policies, and so on) except that multiple threads are used.

JVMS are the next-generation collectors of choice for many JVMS running in Server mode, one of the most important reasons is that they are the only collectors other than Serial that work with older CMS collectors.

Working diagram:


Applicability. 3

New generation collector, parallel multithreaded collector. Its goal is to achieve a controllable throughput (i.e., the ratio of the CPU time spent running user code to the total CPU consumption, i.e., throughput = time spent on lines of user code /[time spent on lines of user code + garbage collection time]) so that the CPU time can be used efficiently to complete the computation tasks of the program as quickly as possible. Suitable for tasks that perform operations in the background without much interaction.

4.Serial Old collector

An older version of the Serial collector, a single-threaded, “mark-up” algorithm, was intended for use by virtual machines in Client mode.

Alternatively, in Server mode:

Use the Parallel Scavenge avenge in versions prior to JDK 1.5

Can be used as a backup solution to CMS in the event of Concurrent Mode Failure

Working diagram:


Parallel Old collector

The Parallel Insane, a multithreaded, “tag collation” algorithm that only appeared in JDK 1.6. To be insane, the Parallel Exploitinsane can only be used with the Serial Old insane

With the advent of the Parallel Old collector, the “throughput first” collector finally has a worthy combination. The Parallel Insane /Parallel Old combination can be used in throughput and CPU sensitive applications. The working diagram of the combination is as follows:


6. CMS collector

CMS(Concurrent Mark Sweep) collector is a collector that aims to obtain the shortest recovery pause time. The pause time is short and the user experience is good.

Based on “mark clearing” algorithm, concurrent collection, low pause, complex operation process, divided into 4 steps:

1) Initial tag: tag only objects that GC Roots can directly associate with, fast, but need to “Stop The World”

2) Concurrent marking: this is the process of tracing the reference chain, which can be executed concurrently with the user thread.

3) re-marking: To correct The marking record of The part of The object whose marking is changed due to The continuous running of The user thread in The concurrent marking stage. The marking time is longer than The initial marking time but much shorter than The concurrent marking time. “Stop The World” is required.

4) Concurrent cleanup: Cleanup marked as recyclable objects can be executed concurrently with user threads

Since the most time-consuming concurrent markup and concurrent cleanup can work with the user thread, the CMS collector’s memory reclamation process and the user thread are generally executed concurrently.

Working diagram:

The CSM collector has three disadvantages:

1) Very sensitive to CPU resources

Concurrent collection does not suspend user threads, but it can slow down the application and reduce overall throughput because it consumes CPU resources.

CMS default number of collection threads =(number of cpus +3)/4; When the number of cpus is more than 4, the collection threads occupy more than 25% of the CPU resources, which may have a great impact on user programs. Less than four, the impact is greater and may be unacceptable.

2) Unable to handle floating garbage (in Concurrent cleanup, new garbage created by user threads is called floating garbage) and may fail Concurrent Mode Failure.

Concurrent clearance needs to reserve a certain amount of memory space, can not like other collectors in the old age almost filled up again for collection; A “Concurrent Mode Failure” occurs if the CMS does not have enough memory reserved for the program. At this point, the JVM enables backup: temporarily enable the Serail Old collector, resulting in another Full GC;

3) Large amount of memory fragmentation: CMS is based on the “mark-clear” algorithm, and a large number of discontinuous memory fragments will be generated without compression operation after clearing, which will cause that when allocating large memory objects, enough continuous memory cannot be found, and another Full GC action needs to be triggered in advance.


7. The G1 collector

G1 (garbage-first) is the collector that jdK7-U4 introduced commercially. G1 is the garbage collector for server-side applications. Its mission is to replace the CMS collector in the future.

G1 collector features:

Parallel and concurrent: it can make full use of the hardware advantages of multi-CPU and multi-core environment and shorten the pause time. Can execute concurrently with user threads.

Generational collection: G1 can manage the entire heap independently without the cooperation of other GC collectors, handling new objects and objects that have been around for a while in a different way.

Space integration: The overall use of the tag collation algorithm, the local use of the copy algorithm (between two regions), no memory fragmentation, no large objects can not find enough contiguity space to trigger GC in advance, which is better than the CMS collector.

Predictable pauses: In addition to pursuing low pauses, a predictable pause time model can be established, which is better than the CMS collector, allowing users to explicitly specify that no more than N milliseconds are spent on garbage collection within a time segment of M milliseconds.

Why predictable pauses?

This is because you can systematically avoid district-wide garbage collection across the entire Java heap.

The G1 collector divides memory into independent regions of equal size, with the concepts of new generation and old generation retained, but no longer physically isolated.

G1 tracks the value of each Region and maintains a priority list in the background.

According to the allowed collection time, the Region with the highest value (garbage-first) is reclaimed First.

This ensures the highest possible collection efficiency in the limited time available.

What if the object is referenced by an object of another Region?

Do I need to scan the entire Java heap to be accurate when determining whether an object is alive? In other generational collectors, this problem also exists (and is more prominent in G1) : Does the new generation have to scan the old generation when collecting? Regardless of G1 or other generational collectors, the JVM uses Remembered Set to avoid global scans: each Region has a corresponding Remembered Set; Each time a Reference data Write operation is performed, a Write Barrier operation is generated. Then check whether the Reference to be written refers to an object in a different Region from the Reference type data (other collectors: check whether old objects refer to new ones). If not, the related references are recorded in the Remembered Set of the Region where the reference points to the object through CardTable.

Adding the Remembered Set scope to the enumeration at the root of the GC ensures that no global scans and no omissions will occur during garbage collection.


Without counting the operation to maintain Remembered Set, the recycling process can be broken down into four steps (similar to CMS) :

1) Initial Mark: only Mark objects that GC Roots can be directly associated with, and modify The value of TAMS(Next Top at Mark Start), so that The Next stage of user programs can create new objects in The correct available Region when they run concurrently. This requires “Stop The World”.

2) Concurrent marking: It takes a long time to conduct reacability analysis from GC Roots to find the living objects, which can be executed concurrently with the user thread

3) Final mark: Correct the mark record of the part of the object whose mark is changed because the user thread continues to run during the concurrent mark stage. During The concurrent marking, The VIRTUAL machine will record The object changes in The thread Remember Set Logs. In The final marking stage, Remember Set Logs will be integrated into The Remember Set. The marking time is longer than The initial marking time but much shorter than The concurrent marking time, which requires “Stop The World”.

4) Filter collection: first, sort the collection value and cost of each Region, then customize the collection plan according to the expected GC pause time of users, and finally collect garbage objects in some high-value regions according to the plan. The replication algorithm is used to copy living objects from one or more regions to another empty Region on the heap, and compress and release memory in the process. It can be done concurrently, reducing pause times, and increasing throughput.

Working diagram:


10: Basic structure

In terms of the logical structure of the Java platform, we can look at the following figure to understand the JVM:

The figure above shows the logic modules included in the Java platform and the differences between the JDK and JRE.


The article is a little long, we think the author’s summary is ok, you can click on the following TWO-DIMENSIONAL code to pay attention to. The “Java Rotten Pigskin” public account is not only about Java technology knowledge, but also about interviews and a lot of architecture. Everyone pay attention to it! Pay attention to rotten pig skin, you will learn more…………..