Hello, today for you children to share JVM, quickly take out a small notebook to write down!
The JVM based
Summary of the JVM
JVM: Java Virtual Machine, also known as Java Virtual Machine, the so-called Virtual Machine refers to a computer system with complete hardware system functions that is simulated by software and runs in a completely isolated environment. JVM is the instruction set of Java bytecode that is simulated by software and is the running environment of Java programs
The main features of the JVM
Find and load class files by ClassLoader
Interprets bytecode files as instructions and executes them, providing a runtime environment for class files
Do runtime memory allocation and garbage collection
Provide a platform to interact with hardware
The JVM classification
Sun/Oracle
VM ancestor: Sun Classic/Exact VM
Wulin Alliance master: HotSpot VM
Home jasper: Moblie/Embedaed VM
BEA company
Number two: JRockit
Soft/hard combination: BEA Liquid VM/Azul VM
IBM
Number two in the world: J9
Apache/Google
Challenge this: Apache Harmony/Google Android Dalvik VM
Microsoft
Failure, but not failure: Micosoft JVM
A hundred schools of thought contend…
Java memory area and memory overflow exception
The JVM consists of two subsystems, the Class Loader and the Execution Engine, and two components. Runtime data area Native Interface Runtime data area Native Interface
ClassLoader: loads the class file into the Method Area of the Runtime data area based on the given fully qualified class name (for example, java.lang.object)
Execution Engine: Executes instructions in classes
Native Interfaces: Interact with Native libraries. Native interfaces are used for interaction with other programming languages
Runtime data area: This is what we call the memory of the JVM
Program Counter Register: The bytecode parser’s job is to change the value of this counter to select the next bytecode instruction to be executed. Branches, loops, jumps, exception handling, thread recovery, and other basic functions depend on this counter
Java Virtual Machine Stacks: This is thread-private and has the same lifetime as a thread and is used to store information about local variables, operand Stacks, dynamic links, method exits, etc
Native Method Stack: Serves the same purpose as the virtual machine Stack, except that the virtual machine Stack serves Java methods, while the Native Method Stack serves Native methods for the VIRTUAL machine
Method Area: Used to store class information, constants, static variables, and code data that has been loaded by the virtual machine
Heap: The largest chunk of memory in the Java virtual machine pool, which is shared by all threads and where almost all object instances allocate memory
Local Library Interface (JNI)
An overview of the
Java Native Interface (JNI) : Java Native development Interface
JNI is a protocol used to communicate Java code with external native code (C/C++), which can also call Java code
Why use JNI
Efficiency C/C++ is a native language that is more efficient than Java
Code migration. If you have previously developed modules in C, you can reuse existing C code
Java decompilation is easier than C decompilation. Most encryption algorithms are written in C and cannot be easily decompilated
In the local method stack, the native method is registered, and the method in the local method library is loaded and called by JNI at the time of final execution
Runtime data area
PC register
Each thread has an OC register, which is thread-private and stores the address to the next instruction
When the thread is created, the corresponding Pc register is created
The VALUE of the PC register is undefined when the local method is executed
Is a relatively small memory space and is the only area where outofMemoryErrors are not specified in the JVM specification
Java stack
A stack consists of a series of frames (frames), so a Java stack is also called a Frame stack and is thread private
Stack frames are used to hold local variables of a method, the operand stack (Java has no registers and uses the operand stack for all arguments passed), constant pool Pointers, dynamic links, method returns, and so on
Each method call creates a frame and pushes the stack. When exiting the method, changing the top pointer destroys the contents of the stack frame
Stack advantage: access faster than the heap block, second only to registers
Disadvantages of stack: the size of data in the stack, the survival area is determined by the compiler, lack of flexibility
The Java heap
Used to store objects and arrays of the application system, all threads share the Java heap
The GC mainly manages heap space, and for generational GC, the heap is also generational
Advantages of heap: dynamic allocation of memory size during runtime, automatic garbage collection
Disadvantages of heap: Relatively slow efficiency
Methods area
Method areas are shared by threads and are typically used to hold structural information about loaded classes
It is usually associated with a meta-space, but it depends on the JVM implementation and version
The JVM specification describes the method area as a logical part of the heap, but it has an alias called non-heap, presumably to separate it from the Java heap
Static variables, constants, class information (constructors, interface definitions), and the run-time constant pool are stored in the method area, but instance variables are stored in heap memory, independent of the method area
Method area development
Previously in JDK8, the HotSpot design team chose to extend the generational design of the collector to the method area, or to implement the method area using persistent generations, which allowed HotSpot’s garbage collector to manage this part of memory as well as the Java heap, eliminating the need to write memory-management code specifically for the method area.
JDK6, constant pool, static variable in method area
After JDK7, the concept of permanent generation is abandoned, and the method area is gradually implemented in Native Memory. The string constant pool and static variables that were originally placed in the permanent generation are removed
In JDK8, the permanent generation is completely abandoned and replaced by Metaspace, which is implemented in local memory like JRockit and J9. The remaining content (mainly type information) of the permanent generation in JDK7 is moved to the Metaspace
Run-time constant pool
Is a constant pool table for each Class or interface in a Class file, which is represented at runtime, usually including: Class version, field, method, interface, etc
Assign in the method area
Typically, after classes and interfaces are loaded into the JVM, the corresponding runtime constant pool is created
Local method stack
The stack used in the JVM to support native method execution is the native method stack
Complete refine THE JVM diagram
Java program running mechanism
The compiler converts Java code into bytecode files. The ClassLoader loads the bytecode files into memory and places them in the methods area of the Runtime data area. Bytecode files are just a set of instructions for the JVM. It cannot be delivered directly to the underlying operating system, so a specific command parser Execution engine is required to translate bytecode into the underlying system instructions for Execution by the CPU. In this process, it is necessary to call the local library interface (Runtime data area) of other languages to realize the function of the whole program
Loading a class involves reading binary data from a.class file into memory, placing it in the method area of the runtime data area, and then creating a java.lang. class object in the heap that encapsulates the class’s data structure in the method area
HotSpot VIRTUAL machine object Exploration
Object creation
How objects are created
The process of creating an object
When the Java virtual machine reaches a bytecode new instruction, it first checks to see if the instruction’s arguments locate a symbolic reference to a class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, the class loading process of the response must be performed first.
After the class load check passes, the virtual machine next allocates memory for the new objects. The size of memory required by an object is fully determined once the class is loaded, and the task of allocating space for an object is essentially the same as dividing a block of memory of a certain size from the Java heap, depending on how tidy the Java heap is
Bump The Pointer: Suppose that The Java heap is fully structured, all used memory is placed on one side, free memory is placed on The other side, and a Pointer is placed in The middle of The Pointer. This is called a “Pointer Bump”.
Space List (Free List) : the Java heap is not neat, have been used memory and Free memory staggered together, that is not possible with a simple pointer collision, the virtual machine needs to maintain a table, record the memory block is available, at the time of distribution from the List to find a large enough space partition for instance objects
In addition to how the space is divided, there is another issue to consider: object creation is a very frequent activity, and even just changing the position of a pointer is not thread-safe in concurrent situations. It is possible that object A is allocating memory and object B uses the original pointer to allocate memory at the same time before the pointer can be modified. There are two possible solutions to this problem
One is to synchronize the operation of allocating memory space. In fact, the VIRTUAL machine uses the CAS and retry mode to ensure atomicity of the update operation
In other words, each Thread allocates a small block of memory in advance, which is called Thread Local Allocation Buffer (TLAB). If the Thread needs to allocate the memory, it allocates the memory in the Local Buffer of that Thread. Synchronization locking is required only if the local buffer allocation is used up and new buffers are allocated.
After memory allocation is complete, the virtual machine must initialize the allocated memory space (but not the object header) to zero. If TLAB is used, this can also be done in advance of TLAB allocation. This ensures that the instance fields of the object can be used in Java code without assigning initial values. Enables the program to access the zero values corresponding to the data types of these fields
The Java virtual machine then has to set up the Object as necessary, such as which class the Object is an instance of, how to find the metadata information of the class, whether the Object is hashed (which is actually delayed until the Object:: Hashcode () method is actually called), the GC generation age of the Object, and so on
After the above work is done, a new object has been created from the Perspective of the Java virtual machine. But from a Java program’s point of view, object creation has only just begun. The —- constructor, the method in the Class file, has not yet been executed. In general, the construction of this Class is determined by the invokespecial instruction that follows the new instruction. Classes generated by other means are not necessarily), so that a truly usable object is fully constructed
Object memory layout
In the HotSpot virtual machine, the object storage layout in the heap memory can be divided into three parts: object Header, Instance Data, and align Padding.
Object header: Contains two types of information (12B)
The first type is used to store the runtime data of the object itself, such as HashCode, GC generation age, lock status flag, thread held lock, bias lock ID, bias timestamp, etc. (8B). The length of data in this part is 32 bits and 64 bits respectively for 32-bit and 64-bit virtual machines. Officially called ** “Make Word” **, “Make Word” is designed to be a dynamically defined data structure to store as much data as possible in a very small space and reuse its own storage space according to the state of the object in order to consider the space efficiency of the virtual machine
The other is a type pointer (4B), which is a pointer to an object’s type metadata that the Java virtual machine uses to determine which class the object is an instance of
Instance data: The valid information that an object actually stores, that is, the contents of the various types of fields that we define in our program code, whether inherited from a parent class or defined in a subclass, must be recorded. (Fields of the same width are always stored together)
Alignment padding: not necessary, no special meaning, just a placeholder, because the automatic memory management system of the HotSpot VIRTUAL machine requires that the object address must be a multiple of 8 bytes, so if the object instance data part is not aligned, it needs to be filled by alignment padding
Object access location
The Java program will use the reference data on the stack to manipulate the specific object on the heap. The Reference type only defines that it is a reference to the object, but does not define how the reference should locate and access the specific position of the object in the heap. So how objects are accessed depends on the implementation of the virtual machine
Handle: With handles, the Java heap may allocate a chunk of memory as a handle pool. Reference stores the address of the handle of the object, and the handle contains the specific address information of the instance data and type data of the object
Direct pointer: The memory layout of the object in the Java heap must consider how to place the information related to the access type data. The direct pointer stored in the Reference is the object address
The biggest benefit of using handles for access is that reference stores a stable handle address, which only changes the instance data pointer in the handle when the object is moved (which is very common in garbage collection), but reference does not
The advantage of using a direct pointer is that it is fast and saves the time cost of a pointer location. Since Java object location is very frequent in Java, this kind of overhead can also add up to a considerable overhead. HotSpot mainly uses the second method to access objects (with exceptions).
An OutOfMemoryError
In addition to the program counter, several other runtime areas of the virtual machine memory are subject to OOM exceptions
The Java heap overflow
The Java heap is used to store object instances. As long as we keep creating objects and ensure that GC Roots have a reachable path to the objects to avoid garbage collection, overflow exceptions will occur as objects grow and the total capacity handles the maximum heap capacity limit.
To solve this problem, a conventional approach is to analyze the heap Dump snapshot by using a Memory image analysis tool. The first step is to determine whether there is a Memory Leak or Memory Overflow.
A memory leak is when an object or variable that is being used remains in memory. In theory, Java has a GC garbage collection mechanism, which means that objects that are not being used are automatically reclaimed by the GC and purged from memory
There are still memory leaks in Java, and it is clear why Java causes memory leaks: A memory leak can occur when a long-lived object holds a reference to a short-lived object. Although a short-lived object is no longer needed, it cannot be reclaimed because a long-lived object holds a reference to it. This is how memory leaks occur in Java
The virtual machine stack and the local method stack overflow
Since HotSpot does not distinguish between virtual machines and local method stacks, there is no point in setting the local method stack size parameter, the stack size can only be set by the -xSS parameter, there are two exceptions
Virtual machine stack: StackOverflowError is raised if the stack depth requested by the thread is greater than the maximum depth allowed by the virtual machine
If the virtual machine’s stack memory allows dynamic scaling, an OutOfMemoryError is raised when the extended stack cannot allocate sufficient memory
Runtime constant pool overflow
The String intern() method is a local method that returns a reference to the String in the String constant pool if the String constant pool already contains a String equal to the String; otherwise, it adds the String contained in the secondary String to the constant pool and returns a reference to the String
In JDK6 and before, the constant pool was allocated to the permanent generation, so you can indirectly limit the constant pool by limiting the permanent generation size by -xx :PermSize and -xx :MaxPermSize. Calling the intern method in a while loop causes the runtime constant pool to overflow. This problem does not occur after JDK7 because the pool of string constants stored in the permanent generation has been moved to the heap
Method area overflow
The method area mainly stores type information, such as class names, access modifiers, constant pools, field descriptions, etc. As long as a large number of classes are constantly generated at runtime, the method area will overflow, such as using JDK reflection or CGLib to directly manipulate bytecode at runtime. Many frameworks, such as Spring and Hibernate, use bytecode technology like CGLib when enhancing classes. The more classes are enhanced, the larger the method area is required to ensure that dynamically generated new types can be loaded into memory, which is easier to cause method area overflow
Vm class loading mechanism
concept
Java files are written to store the business logic code, and the Java compiler compiles. Java files into files with a. Class extension. The.class file holds the instructions to be executed by the virtual machine after Java transformation. When a class is needed, the Java virtual machine loads a. Class file, creates a corresponding class object, and loads the class file into the VM memory. This process is called class loading
Loading time
Implicit loading: new creates an instance of the class
Display loading: loaderClass, forName, etc
Access the static variable of the class, or the value of the static variable
Call a static method of a class
Call reflection to create a Class object for a Class or interface
Initialize a class
Run a class directly using the java.exe command
ForName is different from loaderClass
Class.forname () yields a Class that has already been initialized
Classloader.loaderclass () returns classes that have not yet been connected (validated, prepared, parsed).
Loading process
Class life cycle
Outside the chain picture archiving failure, the source station might be hotlinking prevention mechanism, proposed to directly upload picture preserved (img – pGuiXUh8-1622715816775) (C: / Users/dell/AppData/Roaming/Typora Typora – user – images/I mage-20210528203645415.png)]
Loading: The phase of the class loading process in which the ClassLoader looks for a class bytecode file by its fully qualified name and creates a class object from the bytecode file
Verification: To ensure that the byte stream of a class file meets vm requirements and does not harm VM security, it mainly includes four types of verification: file format verification, metadata verification, bytecode verification, symbol reference verification
Preparation: Allocate memory for the class variable (static int I = 5) and set the initial value of the class variable (static int I = 5). Because final is already assigned at compile time. There is no instance variable allocation initialization, class variables are allocated in the method area, and instance variables are allocated to the Java heap along with the object
The main task here is to replace symbolic references in the constant pool with direct references
Initialization: Initializes the parent class if it has one, executes its static initializer (static code block) and statically initializes member variables. (The default value for static was initialized earlier, so you need to copy it and initialize the member variables.)
Class loaders are used to read the binary byte stream of a Class according to its fully qualified name into the JVM, and then convert it into an instance of the same java.lang.Class object as the target Class object. Four types of loaders are provided in the Java Virtual machine
Class loaders are used to read the binary byte stream of a Class according to its fully qualified name into the JVM, and then convert it into an instance of the same java.lang.Class object as the target Class object. Four types of loaders are provided in the Java Virtual machine
Class loader
A block of code that implements getting the binary byte stream of a class by its fully qualified name is called a class loader
Bootstrap ClassLoader: a part of the VIRTUAL machine that loads libraries in the Java_HOME/lib/ directory or in the path specified by the -xBootclasspach parameter and recognized by the virtual machine
The Extension ClassLoader is responsible for loading all libraries in the Java_HOME\lib\ext directory or in the path specified by the Java \ext\dirs system variable
The Application ClassLoader is responsible for loading the specified class libraries from the user’s classpath. We can use this ClassLoader directly. In general, if we don’t have a custom class loader this is the default
Parental delegation model
From the Perspective of the Java virtual machine, there are only two different class loaders
Bootstrap ClassLoader: this ClassLoader is implemented in C++ and is part of the virtual machine itself
All other classloaders: These classes are Java language implementations, exist independently of the virtual machine, and all inherit from the abstract java.lang.classloader class
Parental delegation model
The parent delegate model requires that all class loaders have their own class loaders, except the top-level start class loaders. However, the parent-child relationship between class loaders is usually not implemented by Inheritance, but rather by Composition, which is a best practice for Java designers to give developers a kind of loader implementation
The working process of the
If a classloader receives a classload request, it first does not attempt to load the class itself. Instead, it delegates the request to the parent classloader. This is true at every level of classloaders, so all loader requests should ultimately be passed to the top level of the starting classloader. As long as the parent loader tells itself that it cannot complete the load request (its search scope does not find the required class), the child loader will try to complete the load itself
advantages
One obvious benefit is that classes in Java have a hierarchical relationship with priority along with their classloaders. For example, the java.langobject class, which resides in rt.jar, is delegated to the launcher class loader at the top of the model by any classloader that loads the class. Therefore, the Object class is guaranteed to be the same class in any classloading environment of the program.
The parental delegation mechanism is important to ensure the stable operation of Java programs
The implementation of the parental delegate model
The loadClass() method of java.lang.classloader
First check whether the requested class has been loaded. If not, the loadClass() method of the parent loader is called. If the parent loader is empty, the startup class loader is used as the parent class loader by default
Break the parent delegate model
One problem with the parent delegate model is that the parent class loader cannot downward identify resources loaded by the child class loader
To solve this problem, a Thread context classloader was introduced, which can be set via Thread’s setContextClassLocader()
When hot deployment is implemented, such as OSGI’s modular hot deployment, its class loaders are no longer strictly based on the parental delegation model, and many may be executed in flat class loaders
Garbage collector and memory allocation strategy
Gerbage Collection (GC)
An overview of the
Garbage collection needs to accomplish three things:
That memory needs to be reclaimed
When to recycle
How to recycle
After half a century of development, today’s dynamic memory allocation and memory reclamation technology is quite mature, everything seems to have entered the “automation” era, so why do you need to understand garbage collection and memory allocation? The answer is simple: when it comes to troubleshooting memory spills, memory leaks, and garbage collection as a bottleneck to higher concurrency, we need to monitor and tune these “automated” technologies
Each part of the Java memory running area, including the program counter, virtual machine stack, local method stack three areas are born with the thread, the thread is extinguished, how much memory needs to be allocated in each stack frame is basically known when the class structure is determined. (even if the compiler makes some optimizations). In general, memory allocation and reclamation in these regions are considered deterministic, so there is no need to worry too much about memory reclamation.
The Java heap and the method area, on the other hand, have significant uncertainties. Multiple implementation classes of an interface may have different memory requirements, and different conditional branches performed by a method may require different memory requirements. What the garbage collector is concerned with is how this portion of memory is managed
Describe the Java garbage collection mechanism
The object is dead
The heap holds all the Java instance objects, and the first thing the garbage collector needs to do before collecting the heap is to determine which of these object Pointers are still alive and which are dead
Reference counting algorithm
An algorithm to determine whether an object is alive or not: add a reference counter to the object, incrementing the counter value by one each time it is referenced; When a reference is invalid, the counter value is reduced by 1, and any reference to an object with a counter value of 0 at any time is an object that cannot be used. Reference counters only take up some extra memory space for counting, but they are simple in principle and highly efficient in judging
However, the Java VIRTUAL machine does not use this algorithm to manage memory for the main reason that this seemingly simple algorithm has a lot of exceptions to consider and must be combined with a lot of extra processing to ensure correct work, such as reference counting alone is difficult to solve the problem of objects referring to each other in a loop
Accessibility analysis algorithm
Java uses the reachability analysis algorithm to determine whether an object is alive or not. The basic idea of this algorithm is to use a series of “GC Roots” root objects as the starting node set. From these nodes, search down according to the Reference relationship, the search path is called the Reference Chain. If there is no reference chain between the object and the GC, then the object cannot be used again
At present, the mainstream garbage collectors all have the feature of local collection. In order to avoid excessive expansion of GC Roots containing too many objects, they have made various optimizations in the implementation
Recovery method area
Since it is not necessary to reclaim the method area, although it is inefficient, it will still throw OOM when the memory is out of use, so we need to know what scenarios need to reclaim the method area. First we need to figure out which objects the method area will reclaim. Prior to JDK1.7, the constant pool was in the method area; in this release and later, it is moved to the heap. As the current version is mainly 1.8 and above, we take 1.8 as the criterion. On this release, garbage classes are mostly recycled. How to determine if a class is useless:
All instances of this class have been reclaimed;
The ClassLoader that loaded the class has been reclaimed;
The java.lang.Class object corresponding to this Class is not referenced anywhere, and the methods of this Class cannot be accessed anywhere through reflection.
Therefore, scenarios where ByteCode frameworks such as reflection, dynamic proxy, CGlib, dynamic JSP generation, and frequent custom Classloaders such as OSGi require the virtual machine to have the ability to unload classes to ensure that the permanent generation, or method area memory, does not overflow.
reference
Reference types in Java
Strongly Reference: The most traditional definition of “Reference”, like “Object obj = new Object()”, in any case, as long as strong references exist, the garbage collector will not reclaim the referenced Object
Soft Reference: Used to describe objects that are useful but not necessary. Before a memory overflow exception occurs, the SoftReference class collects only objects associated with a SoftReference. The SoftReference class implements SoftReference
Weak References: Used to describe non-essential objects that will be reclaimed in the next GC. WeakReference class implements Weak references
PhantomReference: Also known as PhantomReference, the sole purpose of a PhantomReference is to receive a system notification when the object is reclaimed by the collector. The PhantomReference class implements a PhantomReference
Garbage collection algorithm
From the perspective of determining object extinction, garbage collection algorithms can be divided into
Reference Counter GC: Direct garbage collection
Tracing GC: Indirect garbage collection
Generation collection theory
The Weak Generational Hypothesis: the overwhelming majority of subjects were born and died.
The Strong Generational Hypothesis: the more times an object survives a garbage collection, the less likely it is to die.
Together, these two generational hypotheses identify a consistent design principle for several commonly used garbage collectors: the collector should divide the Java heap into different regions and then allocate the collected objects to different regions for storage based on their age (that is, the number of times the object has survived the garbage collection process). It is obvious that if an area most objects are moving in the evening out, through the process of garbage collection, so put together their concentration, every time recycling focuses only on how to keep a small amount of live, not to tag those large objects will be recycled, can at a relatively low cost recovery to a large amount of space; If all that is left are hard-to-die objects, then by centralizing them together, the virtual machine side can recycle the area at a low frequency, which allows for both the time cost of garbage collection and the efficient use of memory space
After the Java heap is divided into different regions, the garbage collector can reclaim only one or some parts of the region at a time, thus creating a collection type classification:
Partial GC: The goal is not to collect the entire heap completely
Minor GC: The goal is to collect only new generation garbage
Major GC: Target only old GC
Mixed GC: Target the whole Cenozoic and part of the old
Full GC: The target is garbage collection of the entire Java heap method and method area
It is also possible to arrange garbage collection algorithms that match the survival characteristics of stored objects in different regions
Intergenerational Reference Hypothesis: Cross-generational references are rare compared to generational references.
This is an implicit corollary that can be deduced from the logic of the first two hypotheses: should two objects that reference each other tend to live or die simultaneously
Heap of generational
Young Gen
Eden the garden of Eden
From Survivor zone
To Survivor
Tenured Gen
Permanent Gen Permanent generation
Mark clearing algorithm
Mark all the objects that need to be reclaimed first, and when the mark is complete, all the marked objects are uniformly reclaimed, or vice versa
advantages
Simple implementation, no need for objects to move
disadvantages
The execution efficiency is not stable. If the Java heap contains a large number of objects, and most of them need to be recycled, then a large number of marking and clearing actions must be performed, resulting in the execution efficiency of both marking and clearing processes decreasing with the increase in the number of objects
Memory fragmentation is a problem. A large amount of non-contiguous memory space is created after marking and cleaning. Too much space fragmentation may cause the program to have to trigger another garbage collection action when it needs to allocate large memory objects in the future
The execution process of the mark-clear algorithm is shown below
Mark copy algorithm
The replication algorithm divides the available memory into two equal pieces by capacity and uses only one piece at a time. When this area of memory is used up, the surviving objects are copied to the other area, and the used memory space is cleaned up again. In this way, the memory is reclaimed for the whole half region every time, and there is no need to consider the complicated situation of memory fragmentation when allocating memory. As long as the heap top pointer is moved, the memory can be allocated in order, which is simple to implement and efficient to run. But the cost of this algorithm is to reduce the memory to half of the original, the waste is larger
Advantages: Memory can be allocated sequentially, simple implementation, efficient operation, do not consider memory fragmentation.
Disadvantages: The available memory size is reduced by half, and objects are frequently copied when they have a high survival rate.
The execution process of the replication algorithm is shown in the following figure
Today’s commercial virtual machines all use this collection algorithm to recover the new generation. According to the special research of IBM, 98% of the objects in the new generation are “live and die”. Therefore, it is not necessary to divide the memory space according to the 1:1 ratio, but to divide the memory into a large Eden space and two small Survivor Spaces. Use Eden and one of the pieces Survivor each time. When recycling occurs, the surviving objects in Eden and Survivor are copied to the other Survivor once and for all. When the collection is made, the surviving objects in Eden and Survivor are copied to another Survivor space at a time. Finally, Eden and the Survivor space that was just used are cleaned up. The default HotSpot VIRTUAL machine size ratio of Eden to Survivor is 8:1, which means that each new generation has 90% (80%+10%) available memory of the entire new generation, and only 10% of the memory is “wasted”.
Tag sorting algorithm
For the old age, when there is less garbage to be recycled, the efficiency is low if the replication algorithm is adopted. The markup operation of the mark-clean algorithm is the same as that of the mark-clean algorithm. The subsequent operation is not just to clean up the objects directly, but to move all surviving objects to one end and update Pointers to their objects after cleaning up useless objects
Advantages: It solves the memory fragmentation problem of mark-clean algorithm.
Disadvantages: Local object movement is still needed, which reduces efficiency to a certain extent.
The execution process of the mark-collation algorithm is shown in the figure below
Generational collection algorithm
Currently, all commercial VMS use the garbage collection algorithm of generational collection. The generational collection algorithm, as its name implies, divides memory into chunks based on the lifetime of objects. Generally including young generation, old generation and permanent generation as shown in the figure:
Garbage collector
If the garbage collection algorithm is the methodology of memory collection, then the garbage collector is the concrete implementation of memory collection. The figure below shows 7 collectors that operate on different generations, including the Serial, PraNew, and Parallel Avenge collectors, and the Serial Old, Parallel Old, AND CMS collectors. There is also a G1 collector for recycling the entire Java heap. The wiring between different collectors indicates that they can be used together
Serial collector (replication algorithm): A new generation of single-threaded collectors, marking and cleaning are single-threaded, the advantage is simple and efficient
ParNew collector (copy algorithm): A new generation of delegate parallel collector, which is actually a multi-threaded version of Serial collector and performs better than Serial on multi-core CPUS
The Parallel Collector. A new generation of Parallel collectors, driven by the pursuit of high throughput and efficient CPU utilization. Throughput = user thread time /(user thread time +GC thread time), high throughput can make efficient use of CPU time, as soon as possible to complete the calculation tasks of the program, suitable for background applications and other scenarios with low requirements for interaction
Serial Old collector (mark-collation algorithm): Old single-threaded collector, an older version of the Serial collector
The Parallel Old Collector (mark-collation algorithm) : the Parallel Collector, throughput first, older version of the Parallel Avenge collector;
CMS(Concurrent Mark Sweep) collector (mark-sweep algorithm) : The old parallel collector aims at obtaining the shortest collector pause time. It has the characteristics of high concurrency and low pause, and pursues the shortest COLLECTOR pause time
G1(Garbage First) : the Java heap parallel collector. The G1 collector is a new collector in JDK1.7. The G1 collector is based on the “mark-collation” algorithm, that is, does not generate memory fragmentation. In addition, the G1 collector differs from its predecessors in that it collects the entire Java heap (including the new generation and the old generation), whereas the first six collectors only collect the new generation or the old generation
CMS garbage collector
CMS, short for Concurrent mark-sweep, is a garbage collector that achieves the shortest collection pause time at the expense of throughput. This garbage collector is ideal for applications that require fast server response. Specify the use of the CMS garbage collector by adding “-xx :+UseConcMarkSweepGC” to the start JVM argument
CMS uses the mark-clean algorithm, so a large number of memory fragments will be generated during GC. When the remaining memory cannot meet the program running requirements, the system will suffer a Concurrent Mode Failure, and the temporary CMS will use Serial Old collector for garbage removal. Performance will be reduced at this point
New generation garbage collector and old garbage collector
Cenozoic recyclers: Serial, ParNew, Parallel Insane
Old collector: Serial Old, Parallel Old, CMS
Whole heap collector: G1
The new generation garbage collector generally adopts replication algorithm. The advantage of replication algorithm is high efficiency, but the disadvantage is low memory utilization. Old-time recyclers generally use a mark-collation algorithm for garbage collection.
Describe how generational garbage collector works
The generation collector has two partitions: old generation and new generation. The default space of the new generation accounts for 1/3 of the total space, and the default space of the old generation accounts for 2/3
The new generation uses the replication algorithm. There are three partitions in the new generation: Eden, To Survivor, and From Survivor. The default ratio is 8:1:1 and the execution process is implemented
Put the Eden + From Survivor into the To Survivor zone
Clear Eden and From Survivor partitions
The From Survivor and To Survivor partitions switch, From Survivor becomes To Survivor, and To Survivor becomes From Survivor
An object that survives every move From Survivor To Survivor is aged +1 and is upgraded To the old generation when age reaches 15 (the default is 15). Large objects also go directly to old generation
In the old days, global garbage collection was triggered when the footprint reached a certain value, usually using a mark-up execution algorithm. These iterations constitute the entire implementation process of generational garbage collection
Memory allocation and reclamation policies
Principle:
Priority allocation to Eden Garden: In most cases, objects are allocated in Eden of the new generation. A Minor GC will be initiated when Eden runs out of space
Large objects are allocated directly to the aged area: Objects that require contiguous large amounts of contiguous memory space, typically long strings or large arrays. Large objects tend to trigger garbage collection early when there is not enough space in memory to get enough contiguous space. HotSpot offers – XX: PretenureSizeThreshold parameters, is greater than the value of the objects directly in the old s allocation, to avoid back and forth between Eden and Survivor replication
Long-lived objects are allocated to the aged area: the virtual machine defines an object age technology for each object, which is stored in the object header. If the first Minor GC survives and can be accommodated by Survivor, the object is moved to Survivor and the age is set to 1. The age of an object increases by 1 each time it survives the Minor GC in Survivor, and when it reaches a certain point (15 by default) it is promoted to the old age. You can run the -xx :MaxTenuringThreshold command to set the threshold for the object to be promoted to the old age
Dynamic object age judgment: To adapt to different memory conditions, the VM does not require the age of the object to reach a threshold to be promoted to the old age. If the sum of all objects of the same age in Survivor is greater than half of those in Survivor, the objects of the same age can enter the old age directly
Space allocation guarantee: Before MinorGC, the VM must check whether the maximum available continuous space of the old generation is greater than the total space of the new generation object. If the maximum available continuous space of the old generation object is greater than the total space of the new generation object
If not satisfied, virtual opportunity view – XX: HandlePromotionFailure parameters are allowed to guarantee failure, if allowed to continue to check whether the old s largest contiguous space available is greater than all previous promotion old s average size of an object, if meet will plunge a Minor GC, Otherwise, change to FullGC once
The risk is that the new generation uses a replication algorithm that uses only one Survivor for memory utilization, and if a large number of objects survive after the Minor GC, the older generation needs to allocate guarantees to receive objects that Survivor cannot accommodate
The JVM tuning
JVM tuning tools
The JDK comes with many monitoring tools, which are located in the BIN directory of the JDK. The two most commonly used view monitoring tools are JConsole and JVisualVM
Jconsole: For monitoring memory, threads, classes, etc in the JVM
Jvisualvm: The JDK comes with a versatile analysis tool, can analyze: memory snapshot, thread snapshot, program deadlock, monitoring memory changes, GC changes, etc.
Sets the parameters for viewing the heap
-xms1024m -xmx1024m -xx :+PrintGCDetails: Prints the heap information
Parameters for JVM tuning
-xMS2G: Indicates that the initial push size is 2g.
-XMX2G: The maximum heap memory is 2g.
-xx :NewRatio=4: Sets the memory ratio between the young and old ages to 1:4.
-xx :SurvivorRatio=8: Set the Eden and Survivor ratio of the new generation to 8:2.
– XX:+UseParNewGC: specifies the use of ParNew + Serial Old garbage collector combination;
-xx :+UseParallelOldGC: Specifies the use of ParNew + ParNew Old garbage collector combination;
-xx :+UseConcMarkSweepGC: specifies the use of CMS + Serial Old garbage collector combination;
-xx :+PrintGC: Enables gc information printing.
-xx :+PrintGCDetails: Prints GC details.
– XX: HeapOnOutOfMemoryError: print of exception information generated *. Hprof files
Analyze OutofMemoryErrors using the JProfile analysis tool
Download the Jprofile9.2 analysis tool
Registration code: [email protected]# 5481-UCJN4a16RVD98 #6038
The configuration is performed in IDEA
Write the test
If you look at the file at the root path, you can see what is causing the OutOfMemoryError exception
Well, that’s all for today’s article, hoping to help those of you who are confused in front of the screen