Java memory model and JVM memory structure

1. JVM memory model

1. JVM and JVM memory structure

(1) JVM composition

insert image description here

(2) Java program execution flow

Java program execution flow: The java source file is compiled into a .class file (JVM file) by the compiler javac.exe, and then executed by java.exe. The JVM can be cross-platform and not completely restricted by the performance of the hardware.

(3) Class loader and parent loading mechanism

① Class loader: The function is to load from any position.
There are three layers of loading:
the first layer is bootstrap, loading system functions, which cannot be obtained by JDK, such as str.getClass().getClassLoader()=null of the String class; the second
layer is the platform loader (JDK1.9) /extended class (extClassLoader) loader (JDK1.8);
the third layer is a custom class App loader, such as user.getClass().getClassLoader() of the User class to obtain XXXAppClassLoader@XXX, on top of it.getParent () can get the second loader.

②Parent loading mechanism: first delegate the loading task to the parent class, and recurse in turn. System classes are taken care of by the system loader, and custom classes are taken care of by other class loaders. It can avoid the repeated loading of system classes and prevent the API library from being tampered with.

(4) JVM memory structure (Java runtime data area)

①Method area: The most important memory area, shared by multiple threads, saves class information (name/member/interface/parent class), reflection mechanism is an important part, and dynamically implements class operations.
② Heap memory (Heap): save the real information of the object, and this memory involves the release problem (GC).
③Stack memory (Stack): The private space of the thread, there will be a stack frame in every method call, and the design principle of first-in-last-out is adopted.
When the memory space is constant, the larger the stack, the fewer the number of threads. No GC is required, and the efficiency is higher than that of the heap.
(1) Local variable table: store local parameters or formal parameters, allowing to reserve 32-bit slots (solt), if the length exceeds 32 bits, you need to open up two consecutive slots (Long, Double) (2
) Operand stack: Performs all method computation operations. First in last out.
(3) Constant pool reference: String/Integer class instance
(4) Method exit: the point where execution resumes after the method is executed
(5) Dynamic link: if the interface calls its implemented method through it,
the more important ones are the local variable table and operation Number stack: such as a=1, b=2, c = (a+b)*4. ① put 1 into the bottom of the operand stack first, ② then save it in the local variable table, the same is true for 2, where the local variable table also records the order (for example, 1 is the first int value), and then put 1 and 2 is taken to the stack, then calculated in the cpu, and then 3 is put back on the stack, and 3 and 4 in the constant pool are taken out to be calculated in the cpu, then put back on the stack, and then 12 is put into the local variable table .
④Program counter: The sequential encoding of the execution instructions, such as ① and ② in the above example, the proportion is almost negligible.
⑤Native method stack: Similar to stack memory, the difference is that it only serves local methods (native modification).

Note: The method area and heap in the runtime data area are shared by threads, and the virtual machine stack, local method stack, and program counter are thread-isolated, and each thread has its own stack.

(5) Memory overflow diagnosis and optimization

①Stack overflow error (StackOverflowError)
a. Too many stack frames: if the recursive call does not set the end condition correctly
b. Too large stack frame: json data conversion, object nested object

Common error 1: java.lang.OutOfMemoryError: unable to create new native thread
Error reason: Stack space is not enough to create additional threads, either too many threads are created, or Stack space is really small

Common error 2: java.lang.StackOverflowError
Error reason: This is also a type of memory overflow error, that is, the overflow of the thread stack, either because there are too many levels of method calls (such as infinite recursive calls), or the thread stack is too small.

Thread running diagnosis 1: CPU usage is too high:
get the process number and find the process with high usage

top

Command to get the process id of the thread, thread id, cpu usage

ps H -eo pid,tid,%cpu | grep 进程号

Convert the thread number into a hexadecimal number: such as 6626->19E2, get the process stack information, and find the thread with 'nid=0X19E2'

jstack 进程id

The '#number' at the very beginning of the problem thread indicates the number of lines where the problem occurs, go back to the code to view

Thread running diagnosis 2: deadlock problem.
The program runs for a long time without results. It may be a deadlock problem.
Obtain process stack information

 jstack 进程id 

Check whether there is 'Fount one Java-level deadlock' in the last 20 or so lines, check the detailed description of the deadlock below and locate the problem,
and then return to the code to locate the code to solve it.

②Heap memory overflow (OutOfMemoryError)
common error: java.lang.OutOfMemoryError: Java heap space
error reason: java heap memory is not enough, or there is an infinite loop in the program

Heap memory diagnosis:
generally use dump file analysis
Method 1: Add parameters to generate files when jvm starts
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/xxx/logs/
Method 2: Directly export
jmap -dump:file=filename.dump [pid]

You can use the jvisualvm that comes with the JDK to analyze the dump file

③JVM tuning three major parameters
-Xss: specifies the size of each thread virtual machine stack (affects the number of concurrent threads)
-Xms: initial value of the heap size (exceeding the initial value will expand to the maximum value)
-Xmx: heap size Maximum value (usually the initial value is the same as the maximum value, because expansion will cause memory jitter and affect the stability of program operation)
Memory jitter: When the memory is insufficient, the expansion and contraction control is required, and when the memory is sufficient, the memory in the expansion area needs to be released, which will cause Additional computational performance impact. You can set the corresponding execution parameters to improve the performance of the program, -Xmx: the maximum initialization memory allocated, -Xms: the maximum allocated memory, -Xmx minus -Xms is equal to the size of the expansion area, you can set the two values ​​​​to equal size, improve performance .

2. GC garbage collection

(1) Conditions for garbage collection

Where garbage collection occurs: The method area and heap in the runtime data area are shared by threads. The method area mainly recycles discarded constants and useless classes. The virtual machine stack, local method stack, and program counter are thread-isolated. So what needs to be focused on is the heap.
Judging whether the object needs garbage collection:
① Pay attention to the program counter, which can be recycled when the number of references is 0, but it cannot solve the situation of circular reference, so it is not commonly used.
②Accessibility analysis algorithm (used by hot spot): relying on gc roots (including static attributes in the virtual machine stack/method area or constants/objects referenced by JNI-java native interface in the local method stack), failing to communicate with gc roots can be recycled

(2) Java reference type

① Strong reference: The default reference type in Java. If an object has a strong reference, it will not be GCed as long as the reference still exists.
②Soft reference: In short, if an object has a weak reference, the object will not be GCed before the JVM OOM occurs (that is, the memory is fully used); the object will be GCed only when the JVM is insufficient in memory. Soft references are used in conjunction with a reference queue. If the object referenced by the soft reference is recycled, the reference will be added to the reference queue associated with it.
③ Weak references (the focus of the Entry class in ThreadLocalMap is discussed here): If the object has only weak references, then the object will be GCed by the garbage collector (the object referenced by the weak reference can only survive until the next GC, when GC occurs, regardless of whether the current memory is sufficient, the object referenced by the weak reference objects will be recycled). Weak references are also used in conjunction with a reference queue. If the weakly referenced object is reclaimed by the garbage collection period, the JVM will add this reference to the reference queue associated with it. If the referenced object can be obtained through the get method of the weak reference, when the referenced object is recycled, calling the get method will return null ④
Phantom reference: Phantom reference is the weakest kind of reference among all references, and its existence is In order to receive a notification after the object associated with the phantom reference is GCed. (The object pointed to cannot be obtained through the get method)

(3) GC processing flow

① Object instantiation needs to be completed using the new keyword. All new objects are opened in the Eden Park, and MinorGC (new generation GC recycling) will occur if the memory in the Eden Park is insufficient.
② If an object still exists after multiple MinorGCs, these objects will enter the survival area. There are two survival areas, one is responsible for saving surviving objects, and the other is responsible for promotion. The two areas can be transformed into each other, and there will always be an empty memory.
③ If the space is not enough, perform old generation GC recovery, execute MajorGC (Full GC, poor performance), if the space can be recovered, continue MinorGC.
④ If MajorGC fails, the memory overflows and an OOM exception is reported.
⑤If the newly created object is too large, it will be directly saved in the old age.

(4) GC recovery algorithm

Young generation recycling algorithm:
use the copy cleanup algorithm (because the object survival efficiency is low, so this algorithm with higher efficiency is used). Divide the memory into multiple blocks. After the memory is used up, copy the living object to another block of memory, and the surviving content will be saved in the old generation. The HotSpot (current JVM standard) virtual machine uses BTP (all objects are stored sequentially in the era of a single CPU)/TLAB (split into different blocks, split according to the number of CPU cores) technology for processing.

Old generation recycling algorithm:
use mark-clear algorithm. Mark the garbage and clean it up at once. Pause program execution during marking for reachability analysis. . Low efficiency and the problem of memory fragmentation.
Use mark-compression algorithm. Based on the mark-clear algorithm, all the marked garbage is moved to one end, and then cleaned up.

Cross-generational reference problem:
Objects in the old generation point to objects in the new generation, and this object will be recycled by mistake during garbage collection in the new generation. Solution – Create a collection of memory set pointers in the new generation to record which objects in the old generation area point to the new generation, instead of scanning the entire old generation area. Note that what is recorded is the area, not the specific object (high maintenance cost). This precision is the card precision, so this memory set is called the card table, and each item of the card table corresponds to 512 bytes of the old generation. The card table also needs to be maintained dynamically. hotspot maintains the card table through a write barrier, and generates a circular notification when an assignment operation of a reference object occurs. Put maintenance code in a post-write barrier.

(5) Garbage collector classification

Garbage collectors are roughly classified into serial collectors and parallel collectors: serial means single-threaded. Except for the earlier Serial/Serial old garbage collectors that are serial, the rest of the garbage collectors are parallel.

The principle of concurrent marking in the parallel collector:
the problem of object disappearance needs to be solved – during the scanning process, an object (1) inserts a new valid reference and (2) disconnects the original valid reference.
Solve problem (1): Incremental update, record new references, rescan incremental update after the end of concurrent marking – CMS collector uses
solve problem (2): original snapshot (SATB), record deleted reference relationship, concurrent After the end, re-judgment whether there are other valid references for the deleted references – used by the G1 collector

①Serial/Serial old garbage collector: serial collector. Single-threaded, other threads have to stop during garbage collection. The new generation adopts the copy algorithm (Serial), and the old generation adopts the marking algorithm (Serial old).

②ParNew: Parallel collector. It is only responsible for the garbage collection of the new generation. Except when the single thread is changed to multi-thread in STW, the others are consistent with serail.
The old generation needs to use serialOld or CMS. For a single-core CPU, serial is more efficient than parNew.

③CMS (concurrent mark swap) garbage collector: Concurrent collection has low pause, the disadvantage is that it takes up cpu resources and cannot clear floating garbage. If the memory reserved in the old generation is not enough, it will fail concurrently (serialold will replace cms for recycling at this time), memory Fragmentation issues – FULLGC occurs when contiguous object allocations cannot be satisfied.
Using -XX:UseCMS-CompactAtFullCollection is enabled by default, and memory defragmentation (compression) can be performed when fullGC occurs.
Use -XX:UseCMSFullGCsBeforeCompaction, the default is 0, and determine the process of compressing
concurrent marking after a few times of Full GC: initial marking (judging whether the object can be connected to gc roots) - concurrent marking - remarking (correcting unprepared points in concurrent marking, such as object disappearing problem) - concurrent cleanup. Where initial marking and re-marking require STW.

④Pararell Scavenge/Parallel old: Parallel, so that garbage collection can reach a state that can control the throughput.
The focus of collectors such as CMS is to shorten the pause time of user threads as much as possible during garbage collection, but it will slow down the application and reduce the total throughput because it takes up a part of the thread (or CPU resources), while Parallel Scavenge The goal of the collector is to achieve a controllable throughput (Throughput).
-XX:MaxGCPauseMills controls the maximum garbage collection pause time, -XX:GCTimeRatio controls the throughput size
-XXUseAdaptiveSizePolicy gc adaptively adjusts the most appropriate pause time and throughput.
Cooperate with Parallel old to handle the old generation. Use when focusing on throughput and sensitivity to cpu resources.

⑤G1 Garbage Collector: Support large memory/support multiple CPUs/reduce STW (Stop the world, MajorGC marking time) time, which can guarantee the execution of programs in concurrent state. The main difference from CMS is the principle of concurrent marking.
It is used by default after JDK1.9, 1.7-1.8: -XX:+UseG1GC.

Use with:
Serial+Serial Old
Parallel Scavenge+Paraller Old
ParNew+CMS

Note: By default, JDK1.8 will select different GC recycling strategies according to different systems. Single-core is serial recycling, and multi-core is parallel recycling. The default operation for JDK1.9-1.11 is G1.

2. Java memory model

1. Basic concepts

JMM (Java Memory model): It is a set of rules for the visibility, order and atomicity of data when multi-threading reads and writes shared data (three elements of concurrent programming).

2. volatile keyword

a. Visibility (the most important feature). A read of a volatile variable always sees the last write to the volatile variable by any thread.
b.Atomicity. The read/write of any (including 64-bit long type and double type) single volatile variable is atomic. However, the composite operation of type a++/a = b is not atomic, and AtomicInteger (combination of volatile and CAS) can guarantee atomicity.
c. Order, that is, prevent reordering of instructions.

The volatile keyword prevents instructions from being reordered through the "memory barrier".
Memory barrier insertion strategy:
Insert a StoreStore barrier in front of each volatile write operation (prohibiting the reordering of previous writes and volatile writes).
Insert a StoreLoad barrier after each volatile write operation (disallowing reordering of volatile writes with possible subsequent reads and writes).
Insert a LoadLoad barrier after each volatile read operation (disallow reordering of volatile reads with subsequent read operations).
Insert a LoadStore barrier after each volatile read (disallow reordering of volatile reads with subsequent writes).
  Among them, the StoreLaod barrier is the key to ensure visibility, because it will flush all the data in the write buffer before the barrier to the main memory.

3. Synchronized, volatile, CAS comparison

Sychronized and lock can solve the problems of visibility, atomicity and order, volatile can solve the problem of visibility and order, and atomic can solve the problem of atomicity.

(1) synchronized is a pessimistic lock, which is preemptive and will cause other threads to block.
(2) volatile provides multi-thread shared variable visibility and prohibits instruction reordering optimization.
(3) CAS is an optimistic lock based on conflict detection (non-blocking)

Guess you like

Origin blog.csdn.net/tttalk/article/details/126734369