@TOC

Do not understand JVM after reading this article you will understand very much, the article is very long, very detailed!!

Let’s think about some questions

How do we developers make Java code known to computers

First of all, the computer is a binary system. He only knows 01010101

For example, we often need to write HelloWord. Java computer is how to recognize the operation of HelloWord. Java is written by our programmers, we can recognize, but the computer does not know

The process of compiling a Java file therefore requires compilation:

  1. Programmer prepared. Java file
  2. Compile to bytecode files from javac. Class :(why compile to class files, because the JVM only knows.class files)
  3. When compiled by the JVM into files that a computer knows (files are everything to a computer system)

(This is a general concept of abstract painting)

Why is Java a cross-platform language

Java has the JVM to mask the underlying hardware from the software level, and the details of the instruction level to make it compatible with various systems

C and C++ need to be compatible with different operating systems at the compiler level. Those who have written C and C++ know that some of the code in different operating systems is different

3 Differences between Jdk and Jre and JVM

Look at the official picture of Java, Jdk includes Jre, Jre includes JVM

The Jvm in the penultimate layer can run on a variety of platforms

Most of the Jre is written in C and C++, and it is the basic class library that we need when compiling Java

The Jdk also includes things other than the Jre that help us compile Java code, as well as tools for monitoring the Jvm

Why learn the JVM

Why learn the Jvm and what it can do

First think: why did Java dominate enterprise development for so many years because: memory management

When do we think about memory management in Java development as opposed to c and C ++ when we think about freeing resources and we just think about business implementation in JavaCopy the code


Then some people might say, why do we need to learn when the Jvm does all this

If: memory problems, memory overflow, memory leakage problem how to doCopy the code

This is like a person, I generally eat what never need to consider into the body that a part, but one day, if eat should not eat is also to enter the hospital


Learn more about the JVM

Note: THE JVM is the Java Virtual machine, and the Java Virtual machine is the JVM

1 JVM runtime data area

What is the runtime data area (that’s where our Java runtime stuff goes)

Parse the JVM runtime data area

2.1 Method Area

  1. The method area is an area of memory shared by all threads that stores data such as class information that has been loaded by the Java virtual machine, constants, static variables, just-in-time compiler compiled code, and so on.
  2. It has a special name, non-heap. OutOfMemoryError is thrown when the method area cannot meet memory allocation requirements.

2.2 Java Heap

  1. The Java heap is the largest chunk of memory managed by the Java Virtual machine. It is an area of memory shared by all threads and created when the virtual machine is started. The sole purpose of this memory area is to hold object instances.
  2. The Java Virtual Machine specification says that all object instances and arrays are allocated on the heap.
  3. The Java heap is the primary area managed by the garbage collector and is therefore also referred to as the “GC heap.”
  4. The Java heap can be divided into the new generation and the old generation from a memory reclamation perspective.
  5. From a memory allocation perspective, a Java heap shared by threads can be partitioned into multiple thread private allocation buffers.
  6. No matter how to divide, it has nothing to do with the storage content, no matter which area, the storage is the object instance, further division is to better reclaim memory, or faster allocation of memory.
  7. According to the Java Virtual Machine specification, the Java heap can be in a physically discontinuous memory space. Most current virtual machines are extensible (controlled by -xmx and -xMS). OutOfMemoryError is thrown if there is no memory in the heap for instance allocation and the heap cannot be extended.

2.3 Program Counter Register

  1. A program counter is a small memory space that can be thought of as: the address (line number) of the bytecode instructions being executed by the current thread
  2. Because Java virtual machine multithreading is implemented by switching threads and allocating processor execution time, each processor will execute instructions in only one thread. Therefore, in order to restore the correct execution position after the thread switch, each thread has an independent program counter, counters between each thread do not affect each other, independent storage. This is called “thread private” memory. The program counter memory area is the only area in the virtual machine where OutOfMemoryError cases are not specified.

Summary: You can also call it a thread counter

Example: The smallest unit of execution in Java is a thread, and a thread executes instructions that ultimately operate on our computer, the CPU. Running on the CPU, there is a very unstable factor called the scheduling policy, and the scheduling policy is based on the time slice, that is, the current nanosecond is allocated to that instruction.

ifThread A is watching liveAll of A sudden, thread B gets A video call, grabs thread A’s time slice, interrupts thread A, and thread A hangsThen, the video call ends, and what exactly should thread A do? Thread is the smallest unit of execution, it has no memory function, it is only responsible for doing, then this memory by:Program counter to record)

2.4 Java Virtual Machine Stacks

  1. The Java virtual machine is thread-private and has the same life cycle as a thread.
  2. The virtual machine Stack 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, and so on.

Explanation: There are units in each virtual machine stack, and the units are stack frames, one stack frame for each method. In a stack frame he has to store local variables, operand stacks, dynamic links, exits, etc.

Parse stack frames:

  1. Local variable table: is used to store our temporary 8 basic data types, object reference addresses, and returnAddress types. (The returnAddress holds the instruction address of the bytecode to be executed after the return.)
  2. Operand stack: Operand stack is used for operations, such as code with I = 6*6, it will operate at the beginning, read our code, calculate, and put in the local variable table
  3. Dynamic links: If I have a service.add() method in my method that links to another method, this is where dynamic links are stored.
  4. Return = return; return = return


Consider: does one method call another method create a lot of stack frames? A: Yes. If there is a dynamic link in a stack to call another method, a new stack frame will be created. The stack is ordered. One stack frame calls another stack frame, and the other stack frame will be placed below the caller

What does stack to heap mean? What does stack to heap mean, how do you use member variables in the stack, you don’t store member variables in the stack, you store an application address, data in the heap in a minute

Does the recursive call itself create a lot of stack frames? Recursively, it also creates multiple stack frames, just going on and on

2.5 Native Method Stack

  1. The native method stack is easy to understand, it is very similar to the stack, but the method with the native keyword stack
  2. It is a service of the virtual machine stack that executes Java methods (that is, bytecode) for the virtual machine
  3. Native keyword method is not visible, you must go to oracle official website to download to see, and most of the source code modified by native keyword is C and C++ code.
  4. In the same way, the native method stack is C and C++ code


3 Java memory structure

The run-time data area was covered above, but there are only a few widgets left

3.1 Direct Memory

  1. Direct memory is not part of the virtual machine run-time data area, nor is it defined in the Java Virtual Machine specification. However, since it is memory, it is bound to be limited by the size of the total native memory (including RAM and SWAP or paging files) and the addressing space of the processor.
  2. NIO(New Input/Output) class is added in JDK1.4, introducing a Channel and Buffer based I/O mode, which can use the native function library to allocate out-of-heap memory directly. Then a DirectByteBuffer object stored in the Java heap acts as a reference to that memory. This can significantly improve performance in some scenarios by avoiding copying data back and forth between the Java heap and the Native heap.

The difference between direct memory and heap memory is as follows: The performance of direct memory is higher than that of heap memory, and the performance of direct memory is better than that of heap memory. The difference is very obvious in the case of multiple read and write operations

Code example :(error changing time value)

package com.lijie;

import java.nio.ByteBuffer;

/** * Direct memory vs. heap memory */
public class ByteBufferCompare {

    public static void main(String[] args) {
        allocateCompare();   // Allocate comparison
        operateCompare();    // Compare read and write
    }

    /** ** Direct memory and heap memory allocation comparison */
    public static void allocateCompare(a) {
        int time = 10000000;    // Number of operations
        long st = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {

            ByteBuffer buffer = ByteBuffer.allocate(2);      // Request for indirect memory allocation
        }
        long et = System.currentTimeMillis();
        System.out.println("In progress" + time + "Heap memory during this allocation operation: Allocation time :" + (et - st) + "ms");
        long st_heap = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(2); // Direct memory allocation request
        }
        long et_direct = System.currentTimeMillis();
        System.out.println("In progress" + time + "Direct memory during this allocation operation: Allocation time :" + (et_direct - st_heap) + "ms");
    }

    /** * Direct memory and heap memory read/write performance comparison */
    public static void operateCompare(a) {
        // If there is an error, make the number smaller
        int time = 1000000000;
        ByteBuffer buffer = ByteBuffer.allocate(2 * time);
        long st = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            buffer.putChar('a');
        }
        buffer.flip();
        for (int i = 0; i < time; i++) {
            buffer.getChar();
        }
        long et = System.currentTimeMillis();
        System.out.println("In progress" + time + "Heap memory for second read/write operation: read/write time:" + (et - st) + "ms");
        ByteBuffer buffer_d = ByteBuffer.allocateDirect(2 * time);
        long st_direct = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            buffer_d.putChar('a');
        }
        buffer_d.flip();
        for (int i = 0; i < time; i++) {
            buffer_d.getChar();
        }
        long et_direct = System.currentTimeMillis();
        System.out.println("In progress" + time + "Direct memory for second read/write operation: read/write time :" + (et_direct - st_direct) + "ms"); }}Copy the code

Test results:

When 10000000 allocate operations are performed, heap memory: allocate Time :98ms When 10000000 allocate operations are performed, direct memory: allocate time :8895ms When 1000000 read/write operations are performed, heap memory: read/write time: 5666ms when the system performs 1000000 read/write operations, the direct memory: read/write time :884msCopy the code

Code source: “Kiwi 0303” link: blog.csdn.net/leaf_0303/a…

3.2 JVM bytecode execution engine

The core component of the virtual machine is the execution engine, which is responsible for the execution of the virtual machine bytecode, which is first compiled into machine code and then executed by ordinary users.

The concept of “virtual machine” is different from that of “physical machine”. The bytecode of a virtual machine cannot be run directly on a physical machine. It can be run on a physical machine only after the JVM bytecode execution engine compiles the bytecode into machine code.

3.3 Garbage collection system

During the program running, a large amount of memory garbage will be generated (some memory objects that do not point to references belong to the memory garbage, because these objects are no longer accessible, the program can no longer use them, and they are dead to the program). In order to ensure the performance of the program running, The Java virtual machine continuously performs automatic garbage collection (GC) as the program runs.

Garbage collection system is the core of Java, is also indispensable, Java has its own garbage cleaning mechanism, developers do not need to manually clean up

Garbage collection mechanism for the JVM

The garbage collection mechanism is referred to as GC

GC is primarily used for Java heap management. The heap in Java is the largest chunk of memory managed by the JVM and is used primarily to hold instance objects of various classes.

4.1 What is the garbage collection mechanism

During the program running, a large amount of memory garbage will be generated (some memory objects that do not point to references belong to the memory garbage, because these objects are no longer accessible, the program can no longer use them, and they are dead to the program). In order to ensure the performance of the program running, The Java virtual machine continuously performs automatic garbage collection (GC) as the program runs.

GC is the random cleanup of unreachable objects in heap memory. Inaccessible objects will not immediately direct recycling, a garbage collector in the execution of a Java program is automatic, cannot enforce the object clearly, even if the programmer can clearly tell a piece of memory has been useless, should be recycled, programmers can’t force the garbage collector to reclaim the memory. The only thing a programmer can do is to “suggest” that the garbage collector be executed by calling the System.gc method, but it is unknown if and when he will execute it. This is also the main disadvantage of the garbage collector. Of course, this disadvantage is not overshadowed by the great convenience it brings to programmers.

Perform GC manually:

System.gc(); // Manually collect garbageCopy the code


4.2 Finalize method functions

  1. The Finalize () method is a method that will be called before each GC operation and you can use it to do the necessary cleanup.
  2. It is defined in the Object class, so all classes inherit it. Subclasses override the Finalize () method to collate system resources or perform other cleanup tasks. The Finalize () method is called on an object before the garbage collector removes it.

Code sample

package com.lijie;

public class Test {
	public static void main(String[] args) {
		Test test = new Test();
		test = null;
		System.gc(); // Manually collect garbage
	}

	@Override
	protected void finalize(a) throws Throwable {
		// called before gc collects garbage
		System.out.println("Methods called before garbage collection by GC"); }}Copy the code


4.3 Differences between Cenozoic era, old age and permanent Generation (method area)

  1. The heap in Java is the largest chunk of memory managed by the JVM and is used primarily to hold instance objects of various classes.

  2. In Java, the heap is divided into two distinct regions: Young and Old.

Never mind why we do it, we have an example, right

  1. In the old days there was only one area. Young is divided into three regions: Eden, From Survivor, and To Survivor.

  2. The purpose of this partition is to enable the JVM to better manage objects in heap memory, including memory allocation and reclamation.

  3. By default, the ratio of Young to Old is 1:2 (specified by the parameter -xx :NewRatio), that is, Young = 1/3 of the heap size. Old = 2/3 heap size.

  4. Among them, the New generation (Young) is subdivided into Eden and two Survivor regions, which are named From Survivor and ToSurvivor respectively to distinguish them.

  5. Default, Edem: From Survivor: To Survivor = 8:1: 1 (can be set by parameter -xx :SurvivorRatio), i.e. Eden = 8/10 of the new generation space size, From Survivor = To Survivor = 1/10 of the new generation space size.

  6. The JVM only uses Eden and one of the Survivor regions at a time to serve objects, so at any given time one of the Survivor regions is always free.

  7. Thus, the actual memory available for the new generation is 9/10 (90%) of the new generation space.

  8. The permanent generation is the method area of the JVM. Here are some virtual machine loaded class information, static variables, constants and other data. Things in this area are much harder to recycle than older and newer generations.

4.3.1 Why should generations be divided like this:

In fact, the main reason is that object partitioning can be stored according to the characteristics of each generation, which is more convenient for recycling. The most appropriate collection algorithm is adopted:

  1. In the new generation, a large number of objects are found dead and only a small number of objects survive in garbage collection, so the replication algorithm is adopted, and only a small amount of the replication cost of the surviving objects can be collected.

  2. In the old age, because the object has a high survival rate and there is no extra space to allocate it, it must use “mark-clean” or “mark-tidy” algorithm.

The New generation is divided into Eden and Survivor (From and To, referred To as one region). Those are the three districts in the old days. The data will be allocated to the Eden region first (except for large objects, which are Java objects that require a large amount of continuous memory). The JVM is triggered to issue a Minor GC when Eden runs out of space. If an object survives one minor-GC and is accepted by a Survivor space, it is moved to a Survivor space. Each time Survivor survives the Minor GC, the age increases by 1. When Survivor reaches a certain age (default: 15), the age of the Survivor is promoted to the middle of the old age, but the age of the old age can be set.

4.3.2 Differences and trigger conditions of Minor GC, Major GC and Full GC
  1. Minor GC refers to garbage collection that occurs in the new generation. Since Java objects are mostly ephemeral, Minor GC is frequent and generally fast.

  2. A Major GC is an old GC, which refers to a GC that occurred in an old era, and it is common to execute a Major GC in conjunction with a Minor GC. Major GC is much slower than Minor GC.

  3. Full GC cleans the entire heap space, including young and old generations

The Minor GC triggers the following conditions:

  1. MinorGC is triggered when Eden is full. That is, when applying for an object, the Eden area is found to be insufficient, then MinorGC will be triggered once.
  2. Size of newly created object > space left for Eden

Major GC and Full GC trigger conditions: Major GC is usually equivalent to Full GC

  1. Average size of objects promoted to old age per promotion > old age remaining space
  2. The number of surviving objects after MinorGC exceeds the remaining space of the old age
  3. The permanent generation space is insufficient
  4. Perform System. The gc ()
  5. CMS GC abnormal
  6. Heap memory allocates large objects


4.4 How can I Determine whether an Object is alive

4.4.1 Reference counting method
  1. Reference counting means that if an object is not referred to by any reference, it is considered garbage. The disadvantage of this method is that it does not detect the presence of rings.

  2. First of all, reference counting algorithms are not used to manage memory, at least not in mainstream Java virtual machines.

  3. Reference counting: Every time an object is created, a counter is bound to that object. Each time there is a reference to the object, the counter increments by one; Each time a reference to it is deleted, the counter decreases by one. Thus, when there is no reference to the object, a counter of 0 means that the object is dead

Advantages of reference counting:

  • Reference counting algorithm is simple to implement and has high judgment efficiency. In most cases, it is a good algorithm.

Disadvantages of reference counting:

  • Reference counting algorithms are not used in mainstream Java virtual machines to manage memory, mainly because it is difficult to solve the problem of circular references between objects.
  • Such as:
package com.lijie;

public class Test {
	public Object object = null;
	public static void main(String[] args) {
		Test a = new Test();
		Test b = new Test();
		/** * the reference counter is invalid */
		a.object = b;
		b.object = a;

		a = null;
		b = null; }}Copy the code

Application scenarios of reference counting method:

  • Don’t use it
4.4.2 Accessibility analysis
  1. The method is to search down from GC Roots, and the search path is the reference chain. When an object does not have any chain of references to GC Roots, it proves that the object is unavailable and can be recycled.

  1. In the figure above, Object1, Object2, Object3, Object4, Object5 are reachable to GC Roots, indicating that they are referenced objects and viable objects cannot be recycled

  2. Object6, Object7, Object8 are related to each other, but they are not reachable to GC Roots, so they are recyclable objects.

Objects that can be used as GC Roots:

1. Objects referenced in the virtual machine stack (local variable table in the stack frame); 2. The class in the method area statically belongs to the reference object; 3. Objects referenced by constants in the method area; 4. Objects referenced by JNI (generally called Native methods) in the Native method stack. Etc.Copy the code

Advantages of the reachability algorithm:

  • Solve the cross-reference problem.

Advantages of the reachability algorithm:

  • At present it has no disadvantage over reference counting

Application scenarios of the reachability algorithm:

  • This is the algorithm used by the mainstream virtual machines


4.5 Garbage collection mechanism Strategy (also known as GC algorithm)

4.5.1 Reference Counting Algorithm (Reference Counting)

Every time an object is created, a counter is bound to that object. Each time there is a reference to the object, the counter increments by one; Each time a reference to it is deleted, the counter decreases by one. Thus, when there is no reference to the object, a counter of 0 means that the object is dead, and the object should be garbage collected.

Advantages of reference counting:

  • The implementation of reference counting algorithm is simple and the judgment efficiency is high.

Disadvantages of reference counting:

  • Reference counting algorithms are not used in mainstream Java virtual machines to manage memory, mainly because it is difficult to solve the problem of circular references between objects.
  • Such as:
package com.lijie;

public class Test {
	public Object object = null;
	public static void main(String[] args) {
		Test a = new Test();
		Test b = new Test();
		/** * the reference counter is invalid */
		a.object = b;
		b.object = a;

		a = null;
		b = null; }}Copy the code

Application scenarios of reference counting method:

  • Don’t use it


4.5.2 Mark-Sweep Algorithm

Stores a marker bit for each object that records its state (alive or dead). It is divided into two stages, one is the marking stage, in this stage, for each object to update the marking bit, check whether the object is dead; The second phase is the clean phase, which cleans up dead objects and performs GC operations.

Advantages of the tag clearing algorithm:

  • Can solve the problem of circular reference
  • Reclaim only when necessary (when out of memory)

Disadvantages of the tag clearing algorithm:

  • To recycle, the application needs to be suspended, which means stop the world.
  • Marking and clearing are inefficient, especially when there are many objects to scan
  • Will cause memory fragmentation (will cause clearly have memory space, but due to discontinuity, apply slightly larger objects cannot do),

Application scenarios of the tag clearing algorithm:

  • This algorithm is generally applied to the old age, because the object life cycle of the old age is relatively long.


4.5.3 Mark-collation algorithm

The tag cleanup algorithm is very much the same as the tag compression algorithm, but the tag compression algorithm addresses memory fragmentation on top of the tag cleanup algorithm (some people call the tag cleanup algorithm “tag compression algorithm”)

The mark-purge method is an improved version of the mark-purge method. Similarly, in the marking phase, all objects are marked as alive and dead. The difference is that in the second stage, the algorithm does not clean up the dead objects directly. Instead, it arranges all the surviving objects into another space, and then cleans up all the remaining objects. This serves the purpose of mark-collation.

Advantages of mark-collation algorithm:

  • To solve the memory fragmentation problem in the token clearing algorithm,

Disadvantages of mark-collation algorithm:

  • In the compression phase, references need to be updated as available objects are moved.

Application scenarios of mark-collation algorithm:

  • This algorithm is generally applied to the old age, because the object life cycle of the old age is relatively long.


4.5.4 Replication Algorithm

The algorithm splits the memory evenly into two parts and uses only one part of the memory at a time. When this part of memory is full, all living objects in the memory are copied to the other memory. Then the previous memory is emptied and only this part of memory is used, and the cycle continues.

This algorithm differs from the mark-collation algorithm in that instead of copying in the same region, it copies all surviving objects into another region.

Advantages of the replication algorithm:

  • In the case of few living objects, high performance, can solve the memory fragmentation and the Java garbage collection algorithm – mark clearance caused by reference update problems.

Disadvantages of the replication algorithm:

  • Some memory will be wasted. However, the memory block size can be adjusted according to the actual situation. If the number of viable objects is large, the performance of the replication algorithm becomes poor.

Application scenarios of the replication algorithm:

  • The replication algorithm is generally used in the Cenozoic era, because the objects in the Cenozoic era generally die overnight and the number of surviving objects is not large, so the efficiency of using the replication algorithm for copying is relatively high.
  • The JVM divides Heap memory into new generation and old generation. The new generation is divided into Eden and two Survivor Spaces, and the replication algorithm is implemented between Eden — >Survivor Space and To Survivor.
  • However, when the JVM applies the replication algorithm, it does not divide memory 1:1, which would be a waste of memory space. The average JVM is 8:1. In other words, the proportion of Eden :From :To area is that 90% of the space can always be used To create objects, and the remaining 10% is used To store the surviving objects after recycling.


4.5.5 Generational Algorithm (the main algorithms are the above four, which are additional)

In this algorithm, the memory is divided into several blocks according to the different life cycle of the object, the new generation and the old age, so that the most appropriate collection algorithm can be adopted according to the characteristics of each age. And you can kind of think about this algorithm in an important way. The new generation of objects live and die quickly, and the number of objects is large, so focusing on scanning this area can greatly improve the efficiency of garbage collection. In addition, the old age object is stored for a long time, so there is no need to scan the old age frequently, avoiding the overhead caused by scanning.

The new generation

  • In the new generation, every time the garbage collector finds that a large number of objects die and only a few survive, the replication algorithm only needs to pay a small amount of the replication cost of the surviving objects to complete the collection.

The old s

  • In the old age, because of the high survival rate of the object, there is no extra space for it to allocate guarantee, it must be “mark clearance or mark collation algorithm for recycling.


5 Garbage Collector

5.1 What is garbage Collector?

  • The garbage collector is a concrete implementation of garbage collection algorithms (reference counting, tag cleaning, tag collation, and copy), and the garbage collectors provided by different garbage collectors and different versions of JVMS may vary considerably.
  • I take JDK8 as the standard:

Seven different generations of collectors are shown: Serial, ParNew, Parallel Insane, CMS, Serial Old, Parallel Old, G1

And their location indicates whether they belong to a Cenozoic or an older collector:

  • Cenozoic collectors: Serial, ParNew, Parallel Insane

  • Collector: CMS, Serial Old, Parallel Old

  • Whole heap collector: G1

There is a line between the two collectors, indicating that they can be used together:

Serial / Serial Old
Serial / CMS
ParNew / Serial Old
ParNew / CMS
Parallel Scavenge / Serial Old
Parallel Scavenge / Parallel Old
G1
Copy the code

5.2 Garbage collector details

Garbage collector The working area Recovery algorithm The worker thread User thread parallelism describe
Serial New belt Replication algorithm Single thread no In Client mode, the new generation collector is default. A simple and efficient
ParNew New belt Replication algorithm multithreading no Multi-threaded version of Serial, preferred in Server mode, can be paired with CMS’s new generation collector
Parallel Scavenge New belt Replication algorithm multithreading no The goal is to achieve manageable throughput
Serial Old Elderly with Mark-tidy Single thread no Serial An older version, used by VMS in Client mode
Parallel Old Elderly with Mark-tidy multithreading no Parallel insane, throughput priority
CMS Elderly with Marked – clear multithreading is Pursue the shortest collection pause time
G1 Freshman belt + senior belt Mark-tidy + copy algorithm multithreading is JDK1.9 default garbage collector
5.2.1 Serial
  • Serial collector: New generation. The oldest collector in development. It is a single-threaded collector that uses only one CPU or thread to complete the garbage collection, and while it is garbage collecting, it must suspend all other worker threads until the collection is complete.

Features:

  1. A new generation collector that uses a replication algorithm to collect new generation garbage.
  2. In a single-threaded collector, all other threads stop working while the GC is working.
  3. Simple and efficient, suitable for a single CPU environment. Single threads have no overhead of thread interaction and therefore have the highest single thread collection efficiency.

Usage:

Set the garbage collector: "-xx :+UseSerialGC" -- add this parameter to explicitly use the garbage collector;Copy the code


5.2.2 ParNew
  • ParNew collector: New generation. A multithreaded version of Serial that starts multiple threads at the same time for garbage collection.

Features:

  1. The New generation collector. The ParNew garbage collector is a multithreaded version of the Serial collector that uses a replication algorithm.
  2. With the exception of multithreading, the behavior and characteristics of the Serial collector are the same.
  3. Only it can be used with the CMS collector.
  4. But not as good as the Serail collector in a single CPU environment, it is better for multithreading.

Usage:

Set garbage collector: "-xx :+UseParNewGC" -- force to use ParNew; Set garbage collector: "-xx :+UseConcMarkSweepGC" -- when CMS is specified, ParNew will be used as the new generation collector by default; Set garbage collector parameters: "-xx :ParallelGCThreads" -- specify the number of garbage collection threads, ParNew default to open the same number of collection threads as the CPU;Copy the code


5.2.3 requires the Parallel Scavenge
  • The Insane. Unlike the focus of ParNew, this collector is more concerned with throughput and completing calculations as quickly as possible.

Features:

  1. The New generation collector.
  2. Copy algorithm is used.
  3. Multithreaded collection.
  4. Different from ParNew: high throughput is the goal (reduce garbage collection time and allow user code to run longer)

Usage:

Set the garbage collector: "-xx :+UseParallelGC" -- add this parameter to explicitly use the garbage collector; Set garbage collector parameters: "-xx :MaxGCPauseMillis" -- control the maximum pause time for garbage collection (in ms) set garbage collector parameters: "-xx :GCTimeRatio" -- Controls the throughput of running programs. Throughput = Code execution time /(code execution time + GC collection time) Set garbage collector parameters:" -xx :UseAdaptiveSizePolicy" -- Memory tuning to be managed by virtual machinesCopy the code


5.2.4 Serial Old
  • Serial Old collector: An older version of Serial that uses the mark-collation algorithm.

Features:

  1. Old age collector, using “mark-collation” algorithm.
  2. Single-thread collection.

Usage:

// how to set JVM parameters is explained below: this is just a sample of the parameters: use the Parallel Scavenge collector on and before JDK1.5, and the Parallel Old collector on and after JDK1.6. It is now used as a fallback for the CMS collector in the event of Concurrent collection failuresCopy the code


5.2.5 Parallnel old
  • Parallnel Old collector uses a mark-collation algorithm.

Features:

  1. For the old days.
  2. The “mark-tidy” algorithm is adopted.
  3. Multithreaded collection.
  4. However, in a single CPU environment, it is better for multithreading than Serial Old collector.

Usage:

To set the garbage collector: "-xx :+UseParallelOldGC" : to specify the use of ParallelOld collector;Copy the code


5.2.6 CMS
  • CMS collector: the old days. Is a collector to obtain the shortest recovery pause time for the goal, suitable for Internet sites or B/S system server.

Features:

  1. For the old age, the marked – clear method is used to remove garbage;
  2. Based on the “mark-clean” algorithm (no compression operation, memory fragmentation);
  3. To obtain the shortest recovery pause time as the goal;
  4. Concurrent collection, low pause;
  5. The CMS collector has three obvious disadvantages: 1. It is very sensitive to CPU resources, and 2. Unable to handle floating garbage, possible “Concurrent Mode Failure” Failure, 3. Large amount of memory fragmentation is generated
  6. The garbage collector thread and the user thread can work (basically) simultaneously

Usage:

To set the garbage collector: "-xx :+UseConcMarkSweepGC" : to specify the CMS collector;Copy the code


5.2.7 G1
  • G1 collector: Generational collector. One of the most advanced developments in collector technology today is a garbage collector for server applications. The G1 is the ultimate CMS improvement, addressing the problem of fragmentation and more memory space. Although the process is similar to a CMS, the underlying principles are completely different.

Features:

  1. Can make full use of multi-CPU, multi-core environment hardware advantages;
  2. Parallelism can be used to Stop The World;
  3. You can also have garbage collection run concurrently with the user program;
  4. Collection by generation, including Cenozoic and old age
  5. The ability to manage the entire GC heap (young and old) independently without needing to be paired with other collectors;
  6. Being able to deal with objects of different eras in different ways;
  7. Application scenarios It can be applied to servers with large memory and multiple processors.
  8. The mark-collation + copy algorithm is used to recycle garbage

Usage:

Set garbage collector: "-xx :+UseG1GC" : specify to use G1 collector; Setting up the garbage collector parameters: "- XX: InitiatingHeapOccupancyPercent" : when the Java heap utilization rate of parameter values, began to concurrent mark phase; The default value is 45. Set garbage collector parameters: "-xx :MaxGCPauseMillis" : set pause time target for G1, default is 200 ms; Set garbage collector parameters: "-xx :G1HeapRegionSize" : set the size of each Region, ranging from 1MB to 32MB. The goal is to have about 2048 regions at the minimum Java heapCopy the code


6 Configuring JVM Parameters

6.1 Description of JVM Memory Parameters

Xms: the initial heap size, given when the JVM starts. -Xmx: indicates the maximum heap size that can be expanded by the JVM if the initial heap space is insufficient. -Xmn: Sets the size of the young generation in the heap. Total heap size = young generation size + Old generation size + persistent generation size. -xx :NewSize=n Sets the initial size of the young generation. -xx :MaxNewSize=n Sets the maximum size of the young generation. -xx :NewRatio=n Sets the ratio between the young generation and the old generation. For example, -xx :NewRatio=3, indicating that the ratio of young generation to old generation is 1:3, and young generation accounts for 1/4 of the sum of young generation + old generation. -xx :SurvivorRatio=n Ratio of Eden zone and two Survivor zones in young generation. Notice that there are two Survivor zones. 8 means two Survivor: Eden =2:8, i.e. one Survivor is 1/10 of the young generation. The default is 8-xss: sets the stack size for each thread. After JDK5, the Java stack size of each thread is 1M, whereas before, the stack size of each thread is 256K. -xx :ThreadStackSize=n ThreadStackSize -xx :PermSize=n sets the initial value of persistent generation -xx :MaxPermSize=n sets the size of persistent generation -xx :MaxTenuringThreshold=n sets the maximum age of young garbage objects. If set to 0, the young generation object passes through the Survivor zone and goes directly to the old generation. -xx :LargePageSizeInBytes=n Sets the memory page size of heap memory -xx :+UseFastAccessorMethods optimizes the performance of getter methods of primitive types -xx :+DisableExplicitGC Does not explicitly call System.gc() during run time, with -xx :+AggressiveOpts enabled by default whether to enable the latest tuning efforts of the JVM development team. For example, compiler optimization, biased locking, parallel generation collection, etc., jdk6 paper after the default start -xx :+UseBiasedLocking whether to enable biased locking, JDK6 default enabled -xnoclassGC whether garbage collection is disabled -xx :+UseThreadPriorities Use local thread priorities, default enabled etc......Copy the code

6.2 GC collector Settings for the JVM

-xx :+UseSerialGC: sets the serial collector with the young collector. -xx :+UseParNewGC: sets the young user to collect in parallel. Can be used in conjunction with CMS collection. Above JDK5.0, the JVM will set itself based on the system configuration, so this value is no longer required. -xx :+UseParallelOldGC: -xx :+UseParallelOldGC: -xx :+UseParallelOldGC: -xx :+UseParallelOldGC: -xx :+UseConcMarkSweepGC: sets the concurrent collector for the old generation. -xx :+UseG1GC: sets the G1 collector, JDK1.9 default garbage collectorCopy the code


6.3 Where are JVM Parameters Set

6.3.1 IDEA Where to set JVM parameters

1. Application of a single project 2. Global configuration

  1. Locate the bin directory in the IDEA installation directory
  2. Find the idea.exe. vmOptions file
  3. Open the file to edit and save.

6.3.2 Where does Eclipse set JVM parameters

1. Configure a single project

Click the small arrow to the right of the green iconClick on: Run Configurations ->VM arguments

2. Configure global JVM parametersModify the Eclipse configuration file in the Eclipse installation directory: eclipse.ini file

6.3.3 Where does the WAR (Tomcat) Package Set JVM parameters

War is definitely deployed on Tomcat, which modifies Tomcat’s JVM parameters

JAVA_OPTS = /bin/catalina.bat; JAVA_OPTS = /bin/catalina.bat;

set "JAVA_OPTS=-Xms512M -Xmx1024M ... And so on for JVM parameters."Copy the code

2. Add Linux to the catalina.sh file in bin of tomcat

JAVA_OPTS=" -xMS512m -xmx1024m... And so on for JVM parameters."Copy the code

6.3.4 Where do Jar packages set JVM parameters

Jar package is simple, generally SpringBoot project into Jar package to run

Java -xms1024m -xmx1024m... Wait for JVM arguments -jar springboot_app.jar &Copy the code


6.4 Tuning Summary

  1. In practice, we can directly equal the initial heap size to the maximum heap size, which has the benefit of reducing the number of garbage collections at runtime and thus improving efficiency.
  2. The larger the initial heap and the maximum heap memory, the higher the throughput, but also according to the actual memory of your computer (server).
  3. It is best to use a parallel collector because it is faster and faster than serial throughput. Of course, the server must be multithreaded
  4. Set the ratio of new generation to old generation in the heap to 1:2 or 1:3. The default is 1:2
  5. Reduce old generation collection by GC. Set the maximum age of garbage objects in the generation. Do not import Java objects that have a large amount of contiguous memory space, because they will go straight to the old age and perform GC if there is not enough memory

Note: The default JVM heap size seems to be about a quarter of the actual memory of your computer.

package com.lijie;

public class Test {
    public static void main(String[] args) {
        System.out.print("Maximum memory");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M"); }}Copy the code

My computer has 8 gigabytes of operating memory

Class loader

7.1 Mechanism and process of class loading

When a program actively uses a class that has not already been loaded into memory, the JVM initializes the class through three steps: load, connect, and initialize. If there are no accidents, the JVM will complete three steps in a row, so these three steps are sometimes referred to collectively as class loading or class initialization.

The Jvm executes the class file

1, load,
  • Loading refers to reading a class’s class file into memory, converting this static data into a runtime data structure in the method area, and generating a java.lang. class object in the heap that represents the class as an access point to the method area’s class data. This process requires the participation of the class loader.

  • Java class loaders are provided by the JVM and are the basis on which all programs run. These class loaders provided by the JVM are often referred to as system class loaders. In addition, developers can create their own classloaders by inheriting the ClassLoader base class.

  • Class loaders can load binary data of classes from different sources, such as: local Class files, Jar package Class files, network Class files, and so on.

  • The end product of Class loading is a Class object in the heap (not the target Class object) that encapsulates the Class’s data structure in the method area and provides the user with an interface to access the method area data structure, the Java reflected interface

2. Connection process
  • When the Class is loaded, a corresponding Class object is generated for it, and the connection phase is then entered, which is responsible for merging the binary data of the Class into the JRE (meaning merging the binary code of the Java Class into the JVM’s running state). Class join can be divided into the following three stages.
  1. Validation: To ensure that the loaded class information complies with the JVM specification and that there are no security issues. It mainly verifies whether it conforms to the Class file format specification and whether it can be loaded by the current virtual machine.

  2. Preparation: The stage of formally allocating memory and setting initial values for class variables (static variables), which will be allocated in the method area

  3. Resolution: symbolic references to the virtual machine constant pool are replaced by byte-reference procedures

3. Initialization
  • The initialization phase is the process of executing the class constructor

    () method. The class constructor < Clinit >() method is generated by combining the assignment actions of all class variables in the class automatically stored by the compiler with statements in the static block, which is executed from top to bottom.

  • When initializing a class, if the parent class has not been initialized, the initialization of the parent class must be triggered first

  • The virtual machine ensures that a class’s

    () methods are locked and synchronized correctly in a multithreaded environment

To sum up: initialization is assigning the correct initial value to a class’s static variable

7.2 Introduction to class loaders

  1. Bootstrap the class loader
  2. Extension class loader
  3. System class loader
  4. Custom loader

Bootstrap Class loader

It is used to load Java core classes. It is implemented in native code and does not inherit from java.lang.ClassLoader (which is responsible for loading all the classes in jre/lib/rt.jar in $JAVA_HOME. Since bootstrap classloaders involve the details of the virtual machine’s local implementation, the developer cannot get a reference to the bootstrap classloader directly, so direct operations are not allowed.

2 Extensions Class Loader

The extended class loader is the Sun.misc.Launcher$ExtClassLoader class implemented by Sun corporation (acquired by Oracle). Implemented in the Java language, it is a static inner class of the Launcher. It is responsible for loading libraries in the <JAVA_HOME>/lib/ext directory or in the bitpath specified by the system variable -djava.ext. dir. Developers can use the standard extension classloader directly.

3 System Class Loader

Called the system (also known as the application) classloader, it is responsible for loading the -classpath option from the Java command, the java.class.path system property, or the JAR package and classpath specified by the classpath variable at JVM startup. A program can obtain the system ClassLoader through the static method getSystemClassLoader() of the ClassLoader. If not specified, user-defined class loaders use this class loader as the parent loader. Implemented by Java language, the parent class loader is ExtClassLoader. (The Java virtual machine uses parent-delegate mode, which refers to delegating requests to the parent class, a kind of task delegation mode.)

Class loaders go through the following eight steps to load a Class:

  1. Check if the Class is loaded, that is, if it is present in the buffer, if so go to step 8, otherwise go to Step 2.
  2. If there is no Parent classloader, then either Parent is the root classloader or is itself the root classloader, and skip to step 4, or step 3 if the Parent classloader exists.
  3. Request to use the parent class loader to load the target class, if successful skip to step 8, otherwise proceed to step 5.
  4. Request to load the target class using the root class loader, skip to step 8 if successful, skip to step 7 otherwise.
  5. The current Class loader attempts to find the Class file and performs step 6 if it finds it, or step 7 if it does not.
  6. Load the Class from the file and skip to step 8.
  7. Throw ClassNotFountException.
  8. Returns the corresponding java.lang.Class object


7.3 Understand the parental delegation pattern

Parents delegate mechanism, its working principle is that if a class loader received class loading request, it will not go to loading, but delegates the request to the parent class loader to execution, if the parent class loader is its parent class loader, further upward, recursive in order, the request will eventually reach the top of start the class loader, If the parent class loader finish class loading can be successfully returns, if the parent class loader cannot complete the task load, child loader will try to load, it is the parents delegate pattern, namely every son is lazy, every time just throw it to the father to do, I also do until my father said it, his son to think of some way to to complete.Advantages of parent delegation: The advantage of using parent delegation is that Java classes have a hierarchy of priorities along with their classloaders. This hierarchy avoids reloading classes. There is no need for the child ClassLoader to load the class once 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.

7.4 Relationship between class loaders

Let’s learn more about the relationship between class loaders (not the inheritance relationship), which can be divided into the following four start class loaders, implemented by C++, no parent class. ExtClassLoader, implemented by Java language, null system class loader (AppClassLoader), implemented by Java language, ExtClassLoader custom class loader, The parent class loader must be AppClassLoader.

8 JVM visualization tools

8.1 Why visualization tools

During the development of large-scale Java applications, it is inevitable to encounter problems such as memory leaks and performance bottlenecks, such as unreleased connections to files, networks, and databases, and unoptimized algorithms. As applications continue to run, the efficiency of the entire system may decrease, or even the system may crash. In order to find these hidden problems in the program, performance analysis tools are often used to analyze and optimize the performance of the application in the later stage of the project development.

8.2 visualVm

VisualVM is a free visualization tool that integrates multiple JDK command line tools to provide you with powerful analysis capabilities for performance analysis and tuning of Java applications. These capabilities include generating and analyzing massive amounts of data, tracking memory leaks, monitoring garbage collectors, and performing memory and CPU analysis, while automatically selecting faster and lighter technologies to minimize the impact of performance analysis on applications and improve the accuracy of performance analysis.

It is part of the Oracle JDK and is located in the bin folder in the JDK root directory. VisualVM itself runs on JDK6 and above, but it can monitor applications up to JDK1.4

Open 8.2.1 visualVm

Jvisualvm.exe in the bin folder at the root of the JDKnote: my JDK11 does not have this tool, I do not know why, I jdK8 found this tool

8.2.2 Local Test project JVM running status

I have several processes locally, this is my IDea toolI run a SpringBoot projectThat’s when the surveillance starts

8.2.3 Testing the JVM running status of the server project

……

8.3 jconsole

JConsole has been introduced since Java 5. JConsole is a built-in Java performance analyzer that can be run from the command line or in a GUI shell. You can easily use JConsole (or its higher-end cousin, VisualVM) to monitor Java application performance and track code in Java.

8.3.1 start JConsole

To start, click jconsole.exe in the JDK /bin directory and it will automatically search for all virtual machine processes running on the machine. Select one of the processes to begin monitoring

The 8.3.2 Remote Connection project is also very simple and basically consistent with visualVm, so you can explore it yourself