In the Java language, a shared memory model is used to achieve information exchange and data synchronization between multiple threads; as shown in the following figure
Program counter: line number indicator of bytecode.
effect:
- The bytecode interpreter reads instructions sequentially by changing the program counter, thereby achieving code flow control, such as sequential execution, selection, looping, and exception handling.
- In the case of multithreading, the program counter is used to record the position of the current thread execution, so that when the thread is switched back, it can know where the thread ran last time.
The program counter is the only memory area where OutOfMemoryError does not occur. Its life cycle is created when the thread is created, and it dies when the thread ends.
Virtual machine stack
Private, life cycle = thread; java execution memory model, the data of each method call is passed through the stack
Composition: consists of stack frames, each stack frame has: local variable table, operand stack, dynamic link, method entry and exit information
Local variable table: store various data types and object references
Native method stack
Similar to the virtual machine stack, the difference is: the virtual machine stack serves the virtual machine execution method, and the local method stack serves the native method used by the virtual machine
heap
The largest piece of memory, created when the virtual machine starts
Purpose: store object instances, arrays
The main area of garbage collection
Method area , storage
1. Class information (name, modifier, etc.),
2. Static constants in the class,
3. Constants defined as final types in the class,
4. Field information in the class,
5. Method information in the class
Divided into constant pool
String, final variable
Class and interface names, field names, descriptors, method names
Static variable
Parent class static member variable, subclass static member variable, parent class construction method, subclass construction method
Metaspace : class information; compiled code
Main memory and working memory
JVM stipulates that all variables are stored in Main Memory. Each thread also has its own working memory (Working Memory). The working memory of the thread saves a copy of the main memory of the variable used by the thread. All operations (reading, assignment, etc.) of the variable must be performed by the thread. The variable in the main memory cannot be directly read and written in the working memory (volatile variables still have a copy of the working memory, but due to its special order of operations, it looks like a direct read and write access in the main memory). Different threads cannot directly access the variables in each other's working memory. The transfer of values between threads needs to be done through the main memory.
So how to achieve visibility between two threads, you can refer to the article Use of volatile: https://blog.csdn.net/Goligory/article/details/89648177
Reasons for memory overflow:
Too much garbage jvm did not recycle in time
1. Too many reference variables use static
2. A large number of recursion and infinite recursion (new objects in recursion)
3. A large number of loops (new objects in the loop) / too many entities in an endless loop
4. The database query to check all records more than 100,000 at a time may cause overflow
5. Does String use too many + operations
The startup parameter memory value is set too small
Reasons for stack overflow:
1. Whether to call recursively, call the method recursively
2. A large number of loops / endless loops
3. Are there too many global variables?
4. Whether the array, list, map are too large
Heap overflow: recursive new object
Memory leak
After the memory is applied for, the memory space that has been applied for cannot be released, and the consequences of memory leakage and accumulation are very serious
1. Frequent memory leaks: multiple executions
2. Occasional memory leaks:
3. One-time memory leak: only execute once, such as the memory allocated in the constructor is not released
4. Implicit memory leak: the program keeps allocating memory and releases the memory after it ends. Strictly speaking, there is no leak, but if it is not released in time, it may cause all memory to be exhausted.
Cause of leak
Long-lived objects holding short-lived objects lead to the holding of their references and cannot be recycled, causing memory leaks
1. Static collection classes cause memory leaks: such as HashMap, vector
2. Listener, not deleted when the object is released
3. Various links are not closed
4. Singleton mode holds external object references
============GC Garbage Collection============================================================================================================================================================================================================================================== ===============================
We need to be familiar with garbage collection, we need to know how it works, why it works, and what are the benefits?
Heap is the main area of GC
After jdk1.8, the permanent generation is changed to meta space, which uses direct memory
How does the JVM determine which objects should be recycled?
Two ways
1. Reference counting method: add a counter to the object, use +1, not -1, but it cannot solve the problem of circular references between objects, java is useless
2. Reachability analysis algorithm:
Using some objects called reference chain GC Roots as a starting point, starting from these nodes and searching downwards, the path traversed is called Reference Chain. When an object is connected to GC Roots without any reference chain (that is, from GC Roots to the The node is unreachable), proving that the object is unavailable
The objects that can be used as GC Root include the following:
- Objects referenced in the virtual machine stack
- Object referenced by static property of method area class
- Constant reference object in method area
Know the object to be recycled, when will it be recycled? How to recycle?
When will it be recycled?
Automatically recycle when cpu is idle
After the heap memory is full
Actively call System.gc()
3 major recycling algorithms
1.标记/清除算法【最基础】
2.复制算法
3.标记/整理算法
jvm采用`分代收集算法`对不同区域采用不同的回收算法。
- Mark-sweep algorithm: mark first, then clear, mark all the objects that need to be recycled, and then uniformly recycle the marked objects, simple, but inefficient, space problems, a large number of discontinuous memory fragments are generated after the mark is cleared, when the program is running When you need to allocate a large object, you can’t find enough contiguous memory and cause space waste
- Mark-defragment algorithm: similar to the mark-clear algorithm, the difference is that the mark-clear does not operate on the remaining objects and causes memory fragmentation. After the mark-defragment is clear, the remaining objects are sorted without memory fragmentation.
The new generation: replication algorithm
Eden,From Survivor,To Survivor
Java objects are generally born in the new generation, which is also a frequent area of GC. In-depth understanding of the JVM virtual machine said that 98% of the object survival rate is very low, suitable for replication algorithms
It optimizes the efficiency of the mark/sweep algorithm and the problem of memory fragmentation, and the JVM does not allocate memory at 5:5 [Due to the low survival rate, there is no need to copy and reserve such a large area, which causes a waste of space, so there is no need to press 1:1 [Original area: reserved space] divide the memory area, but divide the memory into a piece of Eden space and From Survivor, To Survivor [reserved space], the default ratio of the three is 8:1:1
The goal is to collect objects with a short life cycle as soon as possible. In general, newly generated objects in the Eden area are placed in the new generation first. During garbage collection, the surviving objects in the eden area are first copied to the survivor0 area, and then the eden area is cleared. When the survivor0 area is full, the survivor objects in the eden area and survivor0 area are copied to the survivor1 area, and then the eden and survivor0 areas are cleared, and survivor0 is exchanged. The role of the area and the survivor1 area, the next garbage collection will scan the eden area and the survivor1 area, and so on.
If the survivor1 area is not enough to store the survivor objects in the eden area and survivor0 area, the survivor objects are directly stored in the old generation. If the old generation is also full, a FullGC will be triggered, that is, both the new generation and the old generation will be recycled.
The GC that occurs in the new generation is also called MinorGC. MinorGC occurs more frequently, and it does not necessarily trigger when the eden area is full.
Old age: mark-clear; mark-organize
- Heap size: young generation + old generation. The heap size can be specified according to -xms (heap initial capacity), -xmx (heap maximum capacity)
- The new generation default Eden: from: to=8:1:1
- Jvm only serves objects with Eden and one of the Survivor areas at a time. No matter when, there is always a Survivor that is idle.
- The actual memory space available for the new generation is 9/10 of the new generation space
The old generation stores objects with a long life cycle, and the objects that are still alive after n garbage collections in the young generation will be placed in the old generation.
Permanent generation
Mainly store static files, such as java classes, methods, etc. The permanent generation has no significant effect on garbage collection. However, reflection, dynamic proxy, CGLib, etc. may dynamically generate class files. At this time, you need to set up a relatively large permanent generation space for storage.
Large objects and long-lived objects enter the old age
Note: jdk1.8 discards the permanent generation and provides a similar metaspace technology
The reasons for going to permanent generation are:
(1) Strings exist in the permanent generation, which is prone to performance problems and memory overflow.
(2) It is difficult to determine the size of the class and method information, so it is difficult to specify the size of the permanent generation. If it is too small, it will easily cause permanent generation overflow, and if it is too large, it will easily cause the old generation to overflow.
(3) Permanent generation will bring unnecessary complexity to GC, and the recovery efficiency is low
JVM parameters
Specify the minimum and maximum heap memory
-Xms2G -Xmx5G
Reserve new objects in the new generation. Since the cost of Full GC is much higher than that of Minor GC, it is wise to allocate objects in the new generation as much as possible. In actual projects, analyze whether the space allocation of the new generation is reasonable and appropriate according to the GC log. Adjust the size of the young generation through the "-Xmn" command to minimize the situation that new objects directly enter the old generation.
Explicit new-generation memory, two ways to specify
1.-XX:newSize=256m
-XX:MaxNewSize=1024m
2.-Xmn256m
Display the size of the specified meta space
Jdk8 must specify the metabase size, because using direct memory, the virtual machine may run out of system memory
Garbage collector
1. Serial garbage collector
2. Parallel garbage collector
3. CMS garbage collector
4.G1 Garbage Collector
Heap parameter
Collector parameters
Common commands
GC tuning principles
Most Java applications do not require GC optimization on the server; most Java applications that cause GC problems are not because of our parameter setting errors, but code problems; before the application goes online, consider setting the machine's JVM parameters to the best (The most suitable); Reduce the number of objects created; Reduce the use of global variables and large objects (occupying continuous memory space); GC optimization is the last resort method; In actual use, analyzing GC conditions and optimizing code is better than optimizing GC parameters Much more
Tuning strategy
1. New objects are reserved in the new generation, and the size of the new generation is adjusted through -Xmn to minimize the situation that new objects enter the old generation directly
2. Big objects enter the old age
3. Reasonably set the age of the old age object-XX: MaxTenuringThreshold
4. Set a stable heap size
5. Note: GC optimization is not required to meet the following statement
MinorGC execution time is less than 50ms; Minor GC is executed infrequently, about once every 10 seconds; Full GC execution time is less than 1s; Full GC execution frequency is not too frequent, not less than once every 10 minutes
Reference: https://www.cnblogs.com/shenjianjun/p/9512949.html
GC https://www.cnblogs.com/ITPower/p/7929010.html
This quote is quite comprehensive recommendation: https://www.jianshu.com/p/76959115d486