This article is reproduced. Original article address: http://blog.csdn.net/willfcareer/archive/2010/09/27/5910557.aspxjvmlearning notes (1) ------ Basic Structure
From the logic structure of the Java platform, we can always understand JVM:
The differences between JDK and JRE can be clearly seen from the various logic modules included in the Java platform.
For the physical structure of the JVM itself, we can have a bird's eye view:
In my opinion, the following aspects of JVM learning are the most important:
- Java code compilation and execution process
- JVM memory management and garbage collection mechanism
The following describes the two parts in detail.
JVM learning notes (ii) ------ Java code compilation and execution process
Java code compilation is completed by the Java source code compiler. The flowchart is as follows:
The execution of Java bytecode is completed by the JVM execution engine. The flowchart is as follows:
The entire Java code compilation and execution process includes the following three important mechanisms:
- Java source code compilation Mechanism
- Class Loading Mechanism
- Class execution mechanism
Java source code compilation Mechanism
Java source code compilation consists of the following three processes:
- Analysis and input to symbol table
- Annotation Processing
- Semantic Analysis and generation of class files
The flowchart is as follows:
The generated class file consists of the following parts:
- Structure information. Including the version number of the class file format and the quantity and size of each part
- Metadata. Corresponds to the declaration and constant information in Java source code. Contains the declaration information, domain and method declaration information, and constant pool of classes/inherited superclasses/Implemented interfaces
- Method information. Corresponds to the statements and expressions in the Java source code. Including bytecode, exception processor table, evaluation stack and local variable area size, evaluation stack type record, debugging Symbol Information
Class Loading Mechanism
JVM class loading is completed by classloader and its sub-classes. The class hierarchy and loading sequence can be described from the following:
1) bootstrap classloader
Loads all the classes in JRE/lib/RT. jar in $ java_home, implemented by C ++, not the classloader subclass.
2) Extension classloader
Loads some jar packages for the extended functions of the Java platform, including the jar packages under the specified directory of JRE/lib/*. jar or-djava. Ext. dirs in $ java_home.
3) app classloader
Records the specified jar package in classpath and the class in the directory.
4) custom classloader
Classloader defined by applications according to their own needs. For example, Tomcat and JBoss implement classloader based on J2EE specifications.
During the loading process, the system first checks whether the class has been loaded. The check sequence is from bottom to top. From custom classloader to bootstrap classloader, this class is regarded as loaded as long as a classloader has been loaded, make sure that this class is only loaded once by all classloader. The order of loading is from top to bottom, that is, the upper layer tries to load this type.
Class execution mechanism
JVM executes class bytecode Based on the stack architecture. After a thread is created, a program counter (PC) and a stack are generated. The program counter stores the offset of the next command to be executed in the method. Stack frames are stored in the stack, each stack frame corresponds to each call of each method, and the stack frame is composed of a local variable area and an operand stack. The local variable area is used to store local variables and parameters in the method, the operand stack is used to store intermediate results generated during method execution. Shows the stack structure:
JVM Study Notes (iii) ------ memory management and garbage collection
JVM memory Composition
The JVM stack consists of the heap, stack, local method stack, and method zone. The structure is shown as follows:
1) Heap
The memory of all objects created through new is allocated in the heap, and their size can be controlled through-xmx and-XMS. The heap is divided into the new generation and the old generation, and the new generation is further divided into the Eden and elastic vor areas. Finally, the elastic vor consists of the from space and to space. The structure is shown below:
- New generation. The newly created objects are allocated memory by the new generation. When the Eden space is insufficient, the surviving objects are transferred to the same vor. The new generation size can be controlled by-xmn, or-XX: limit vorratio to control the ratio of Eden to limit vor
- Old Generation. Used to store objects that are still alive after repeated garbage collection in the new generation.
- Permanent generation
Used to store static files. Currently, Java classes and methods are supported. Persistent generation has no significant impact on garbage collection, but some applications may dynamically generate or call some classes, such as hibernate, in this case, you need to set up a large persistent storage space to store the classes added during the running process. The persistent generation size is set through-XX: maxpermsize =.
For example, when an object is generated in a program, a normal object will allocate space in the young generation, if the object is too large, it may also be generated directly in the old generation (it is observed that a 10 MB space is generated each time when a program is running, and messages are sent and received, this part of memory will be allocated directly in the old generation ). The young generation will initiate memory reclaim when the space is allocated. Most of the memory will be recycled, and some of the surviving memory will be copied to the from Area of the same vor, after multiple recycles, if the from Area Memory is allocated, the memory is recycled and the remaining objects are copied to the to area. When the to zone is full, memory will be recycled again and the surviving objects will be copied to the old zone.
In general, the JVM memory recycle always refers to the heap memory recycle. It is true that only the content in the heap is dynamically applied for allocation, therefore, the young and old generations of the above objects refer to the heap space of the JVM, while the persistent generation is the method area mentioned earlier and does not belong to the heap.
2) Stack
Each thread applies for a stack frame in the stack when executing each method. Each stack frame includes the local variable zone and the operand stack, used to store temporary variables, parameters, and intermediate results in the method call process.
3) Local method Stack
It is used to support native method execution and stores the status of each native method call.
4) Method Area
Stores information about the classes to be loaded, static variables, final constants, attributes, and methods. JVM uses permanet generation to store the method area. You can use-XX: permsize and-XX: maxpermsize to specify the minimum and maximum values.
Garbage Collection Mechanism
JVM uses different garbage collection mechanisms for the new generation and old generation respectively.
GC of the new generation:
The new generation usually has a short survival time, so it is recycled Based on the copying algorithm. The so-called copying algorithm is to scan the surviving objects and copy them to a new space that is completely unused, corresponding to the new generation, that is, copy between Eden and from space or to space. The new generation uses the idle pointer Method to Control GC triggering. the pointer keeps the last allocated object in the new generation interval. When a new object needs to be allocated memory, it is used to check whether the space is sufficient, if not, GC is triggered. When objects are continuously allocated, the objects gradually change from Eden to movie vor, and finally to the old generation,
You can use Java visualvm to check whether the new generation is full. After the new generation is full, the object is transferred to the old generation, and then the old generation is full, an outofmemory exception is reported, as shown in:
On the execution mechanism, JVM provides the serial GC (Serial GC), parallel GC (parallel scavenge), and parallel GC (parnew)
1) Serial GC
The whole scanning and replication process is carried out in a single thread mode. It is applicable to applications with a single CPU, small new generation space, and not very demanding on the pause time. It is the default GC method at the client level, you can use-XX: + useserialgc to forcibly specify
2) Parallel GC recovery
The entire scanning and replication process adopts the multi-thread method. This method is applicable to applications with multiple CPUs and short pause time requirements. It is the default GC method at the server level.-XX is available: + useparallelgc is used to forcibly specify the number of threads.-XX: parallelgcthreads = 4 is used to specify the number of threads.
3) Parallel GC
Used in combination with the concurrent GC of the old generation
GC of the old generation:
Unlike the new generation, the old generation and the new generation have a long and stable object survival time. Therefore, the mark algorithm is used for collection. The so-called mark is to scan the surviving object, then, the unmarked objects are recycled. After the unmarked objects are recycled, the empty space is either merged or marked to facilitate the next allocation. In short, the efficiency loss caused by memory fragmentation is reduced. On the execution mechanism, JVM provides serial GC (Serial MSC), parallel GC (parallel MSC), and concurrent GC (CMS). Details of specific algorithms need to be further studied.
The preceding GC mechanisms need to be used in combination. The following table lists the specific methods:
Method |
New Generation GC |
GC method of the old generation |
-XX: + useserialgc |
Serial GC |
Serial GC |
-XX: + useparallelgc |
Parallel GC recovery |
Parallel GC |
-XX: + useconemarksweepgc |
Parallel GC |
Concurrent GC |
-XX: + useparnewgc |
Parallel GC |
Serial GC |
-XX: + useparalleloldgc |
Parallel GC recovery |
Parallel GC |
-XX: + useconemarksweepgc -XX: + useparnewgc |
Serial GC |
Concurrent GC |
Unsupported combination |
1.-XX: + useparnewgc-XX: + useparalleloldgc 2.-XX: + useparnewgc-XX: + useserialgc |
JVM Study Notes (4) ------ memory Tuning
The first thing to note is that when tuning the JVM memory, you cannot only view the memory occupied by the operating system-level JAVA process. This value cannot accurately reflect the actual usage of the reactor memory, this value does not change after GC, so we need to use more memory viewing tools provided by JDK during memory optimization, such as jconsole and Java visualvm.
The main purpose of JVM memory system-level optimization is to reduce the GC frequency and the number of full GC, excessive GC and full GC occupy a lot of system resources (mainly CPU), affecting the system throughput. Pay special attention to full GC, because it will organize the entire heap, resulting in full GC generally due to the following situations:
- Insufficient space for the old generation
During optimization, try to reclaim objects during the new generation of GC, so that objects can survive for a longer period of time in the new generation, and do not create too large objects or arrays to avoid directly creating objects in the old generation.
- Insufficient space for pemanet generation
Increase perm Gen space to avoid too many static objects
- The average size of the statistical GC post-promotion to the old generation is greater than the remaining space of the old generation.
Control the ratio of new generation to old generation
- System. GC () is displayed and called
Do not trigger garbage collection manually. Try to rely on the JVM mechanism.
After learning about this, I will repost some suggestions on memory management from richen Wang, a tech-savvy guy --
1. manually set the generated useless object and the intermediate object to null to accelerate memory recovery.
2. Object pool technology if the generated object is a reusable object, but its attributes are different, you can use the object pool to generate fewer objects. If there are idle objects, they will be taken out and used from the object pool, without generating new objects, which greatly improves the object reuse rate.
3. JVM tuning improves the garbage collection speed by configuring JVM parameters. If memory leakage does not occur and the above two methods cannot guarantee the garbage collection, you can consider using JVM optimization, but it must be tested on the physical machine for a long time, because different parameters may cause different effects. For example, the-xnoclassgc parameter.
Two recommended memory detection tools
1. jconsole JDK's built-in memory monitoring tool. You can run jconsole.exe In the JDK bindirectory by double-clicking. There are two connection modes: the first is local mode, for example, the process running during debugging can be directly connected, and the second is remote mode, which can be connected to the process started as a service. Remote connection: Add-DCOM to the JVM startup parameter of the target process. sun. management. jmxremote. port = 1090-DCOM. sun. management. jmxremote. SSL = false-DCOM. sun. management. jmxremote. authenticate = false
1090 indicates that the listening port number must be modified when used, and then connected by IP and port number. The tool can monitor the memory size, CPU usage, and class loading at that time, and also provides the manual GC function. The advantage is high efficiency and fast speed. It can monitor the operation of the product without affecting its operation. The disadvantage is that you cannot see specific information such as classes or objects. The usage method is simple. You can click a few times to know how the function works. If you do not understand it, You can query documents online.
2. jprofiler is a paid tool, but there are solutions everywhere. After the installation is complete, configure a local session according to the configuration debugging method to run. It can monitor the memory, CPU, thread, and so on at that time, specifically list the memory usage, and analyze a class. There are many advantages and disadvantages that affect the speed, and some classes may not be woven into the method. For example, when I use jprofiler, the backup has never been successful, and there will always be some class errors.
The optimization method is mainly implemented by controlling the ratio of each part of the heap memory and the GC policy. The following describes the consequences of the improper configuration of each part.
1) The new generation is too small.
First, the GC frequency of the new generation is very frequent, which increases the system consumption. Second, the large objects directly enter the old generation, occupying the remaining space of the old generation, and inducing full GC.
2) The new generation is too large.
First, the new generation was too small because the old generation was too small (the total heap volume was fixed), resulting in full GC. Second, the time consumption of the New Generation GC increased significantly.
Generally, the new generation accounts for 1/3 of the total heap.
3) The value of VOR is too small.
As a result, objects are directly transferred from Eden to the old generation, reducing the survival time of the new generation.
4) The value of VOR is too large.
This causes the Eden to be too small and increases the GC frequency.
In addition, the survival time of the new generation is controlled through-XX: maxtenuringthreshold = n, and objects are recycled in the new generation whenever possible.
From the previous blog post JVM Study Notes (iii) ------ memory management and garbage collection, we can see that both the new generation and old generation have multiple GC strategies and combinations, selecting these policies is difficult for our developers. JVM provides two simple methods for setting GC policies.
1) throughput first
Based on the throughput, the JVM selects the corresponding GC policy and controls the ratio of the new generation to the old generation to achieve the throughput. This value can be set by-XX: gctimeratio = n.
2) The pause time takes priority.
Based on the pause time, the JVM selects the corresponding GC policy and controls the size ratio of the new generation to the old generation, make sure that the application stop time caused by GC is within the specified value range. This value can be set by-XX: maxgcpauseratio = n.
Summary of common JVM configurations
- Heap settings
- -XMS: initial heap size
- -Xmx: Maximum heap size
- -XX: newsize = N: Set the young generation size
- -XX: newratio = N: Ratio of the young generation to the old generation. For example, if the value is 3, the ratio of the young generation to the old generation is. The young generation accounts for 1/4 of the young generation and the old generation.
- -XX: Ratio vorratio = N: Ratio of the Eden zone in the young generation to the two region vor zones. Note that there are two vor zones. For example, 3 indicates EDEN: Primary vor =. One primary vor zone accounts for 1/5 of the young generation.
- -XX: maxpermsize = N: sets the persistent generation size.
- Collector settings
- -XX: + useserialgc: sets the serial collector.
- -XX: + useparallelgc: set parallel collectors
- -XX: + useparalledloldgc: sets the parallel elder generation collector.
- -XX: + useconcmarksweepgc: sets the concurrent collector.
- Garbage collection statistics
- -XX: + printgc
- -XX: + printgcdetails
- -XX: + printgctimestamps
- -Xloggc: Filename
- Parallel collector settings
- -XX: parallelgcthreads = N: set the number of CPUs used for parallel collector collection. Number of parallel collection threads.
- -XX: maxgcpausemillis = N: sets the maximum pause time for parallel collection.
- -XX: gctimeratio = N: Set the percentage of the garbage collection time to the running time. The formula is 1/(1 + n)
- Concurrent collector settings
- -XX: + cmsincrementalmode: Set to incremental mode. Applicable to a single CPU.
- -XX: parallelgcthreads = N: set the number of CPUs used when the concurrent collector is used for collecting data in parallel in the young generation. Number of parallel collection threads.