This is the 11th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

JVM Space Description

  • In JDK1.7 and before, HotSpot virtual machines stored data such as Java class information, constant pools, static variables, and code compiled by real-time compilers in Perm (permanent tape) (there is no concept of permanent tape for other virtual machines such as BEA JRockit and IBM J9). Class metadata and static variables are allocated to Perm when the class is loaded. When the constant pool is reclaimed or the class is unloaded, the garbage collector reclaims this part of the memory, but the effect is not very good.

  • In JDK1.8, the HotSpot virtual machine has modified the JVM model by placing class metadata in local memory and constant pools and static variables in the Java heap. HotSpot VM will explicitly allocate and free local memory for class metadata. Under this architecture, Class metadata breaks the -xx :MaxPermSize limit, so this configuration is invalid and more local memory can now be used. This somewhat solves the problem of generating a large number of classes at runtime, which often leads to Full GC — using reflection, proxies, etc.

Dry point

One of the most obvious changes you can see is the shift of the meta-space from the virtual machine to local memory. By default, the metadata space size is limited to local memory only, which means that there will no longer be an OOM exception thrown if the permanent generation is not large enough.

** before jdk1.8, HotSpot VM stored class and class JAR data in PermGen,

PermGen’s size is fixed and there is no common class between projects, so it’s easy to run into OOM exceptions. When I change it to MetaSpace. 支那

Projects share the same class space. For example, if several projects reference apache-common, MetaSpace will store only one copy of the Apache-common class, which improves memory utilization and makes garbage collection more efficient.

Minor GC – The specific process of replication algorithm:

  • The remaining objects in Eden and S0 are copied to S1 once, and the space between Eden and S0 is cleared. If S1 can’t fit any of the objects that are still alive, they will enter the old age through the allocation guarantee mechanism. In principle, keep S0 and S1 empty at all times to save the next object.

  • When Eden is about to be full, a similar operation will be performed in the previous step. Eden and the older objects in S1 will be placed in S0.

  • Until Eden is almost full, and S0 or S1 is almost full, then the older objects in both blocks are placed in the Old block.

  • Loop in turn until the Old area is almost full, and the Eden area is almost full. Then the entire memory area will be cleaned (FullGC) to free up memory for subsequent object creation and program running.


  • Minor GC (GC) : Garbage collection occurs in the new generation. Since Most Java objects are born and die soon, Minor GC occurs frequently and is collected quickly.
  • A Major GC/Full GC is a GC that takes place in the old era. A Major GC is associated with a MinorGC at least once. Be insane.
  • The Major GC is typically more than 10 times slower than the Minor GC.

After upgrading JDK1.8, the above perM configuration has become

-XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M
Copy the code

MetaspaceSize If not configured, check the default MetaspaceSize size (about 21mb) through jInfo. MaxMetaspaceSize is very, very large. As mentioned earlier, MetaSpace is only limited by local memory size.

-xx :MetaspaceSize=21807104 jinfo -flag MetaspaceSize 1234 -XX:MaxMetaspaceSize=18446744073709547520 jinfo -flag MaxMetaspaceSize 1234Copy the code

Dry: MetaspaceSize is the threshold for triggering FullGC. The default is about 21M. If configured, the minimum threshold is the user-defined configured size. The space usage reaches the threshold, triggering FullGC and enlarging the value. Of course, if the actual usage of the meta space is less than the threshold, this value will also be narrowed during GC.

MaxMetaspaceSize is the maximum value of the meta space. If the value is too small, it may cause frequent FullGC and even OOM.


The -xx parameter is called an unstable parameter, so called because setting such parameters can easily cause a difference in JVM performance, making the JVM extremely unstable. If set properly, this type of parameter can greatly improve the performance and stability of the JVM.

Syntax rules for unstable parameters:

Boolean type parameter value

  • -xx :+ ‘+’ indicates that this option is enabled
  • -xx :- ‘-‘ disables this option

Numeric type Parameter values:

-xx := Sets the option to a numeric value that can be followed by units, such as’m ‘or’m’ for megabytes; ‘k ‘or ‘k’ kilobytes; ‘g ‘or ‘g’ gigabytes. 32K is the same size as 32768.

String parameter values:

-xx := Sets an option to a string value, usually used to specify a file, path, or list of commands.

-XX:HeapDumpPath=./dump.core
Copy the code

Sample JVM Parameters

-xmx4g - Xms4g - Xmn1200m - Xss512k -xx :NewRatio=4 -xx :SurvivorRatio=8 -xx :PermSize=100m -xx :MaxPermSize=256m -XX:MaxTenuringThreshold=15Copy the code

Resolution:

  • -XMx4G: The maximum heap memory is 4GB.
  • -xms4g: sets the initial heap memory size to 4GB.
  • -Xmn1200m: sets the young generation size to 1200MB. Increasing the size of the young generation will reduce the size of the old generation. The value has a significant impact on system performance. Sun officially recommends that the value be 3/8 of the entire heap.
  • -Xss512k: sets the stack size for each thread. After JDK5.0, the stack size of each thread is 1MB, whereas before, the stack size of each thread is 256K. This should be adjusted according to the amount of memory required by the application thread. With the same physical memory, reducing this value can generate more threads. However, the operating system has a limit on the number of threads in a process, which cannot be generated indefinitely. The experience value is about 3000~5000.
  • -xx :NewRatio=4: Sets the ratio of the young generation (including Eden and two Survivor zones) to the old generation (excluding the persistent generation). If the value is set to 4, the ratio of the young generation to the aged generation is 1:4, and the young generation occupies 1/5 of the whole stack
  • -xx :SurvivorRatio=8: sets the ratio of Eden and Survivor zones in the young generation. Set to 8, the ratio of two Survivor zones to one Eden zone is 2:8, and one Survivor zone accounts for 1/10 of the entire young generation
  • -xx :PermSize=100m: the permanent generation size is initialized to 100MB.
  • -xx :MaxPermSize=256m: sets the persistent size to 256MB.
  • -xx :MaxTenuringThreshold=15: Sets the maximum age of garbage. If set to 0, the young generation object enters the old generation without passing through Survivor. For applications with more aged generations, efficiency can be improved. If this value is set to a large value, the young generation object will be copied multiple times in the Survivor area, which increases the lifetime of the object in the next young generation and increases the probability that the object will be reclaimed in the young generation.

JVM tuning targets

When do YOU need to do JVM tuning?

Heap memory (old) continues to rise to the set maximum memory value. Full GC frequency is frequent; The GC pause time is too long (more than 1 second); The memory, such as OutOfMemory, is abnormal. The application uses the local cache and occupies a large amount of memory space. The system throughput and response performance are low or degraded. JVM tuning principles

  1. Most Java applications do not require JVM optimization on the server;

  2. Most Java applications that cause GC problems are not because we set the parameters wrong, but because of the code;

  3. Before the application goes live, consider setting the JVM parameters of the machine to the best (most suitable);

  4. Reduce the number of objects created;

  5. Reduce the use of global variables and large objects;

  6. JVM optimization is a last resort;

  7. In practice, it is better to optimize code by analyzing GC situations than by optimizing JVM parameters;

JVM tuning targets

  • GC low pause;

  • GC low frequency;

  • Low memory usage;

  • High throughput;

JVM tuning quantification target (example) :

  1. Heap memory usage <= 70%;

  2. Old Generation memory usage <= 70%;

  3. Avgpause <= 1 second;

  4. Full GC count 0 or AVG pause interval >= 24 hours;

Note: JVM tuning quantification goals vary from application to application.

JVM tuning experience

Summary of JVM tuning experience

The general steps for JVM tuning are:
  • Step 1: Analyze GC logs and dump files, determine whether optimization is needed, and determine the bottleneck points;

  • Step 2: Determine the JVM tuning quantification goal;

  • Step 3: Determine JVM tuning parameters (adjusted based on historical JVM parameters);

  • Step 4: Tune a server and observe the difference before and after tuning.

  • Step 5: Keep analyzing and tuning until you find the right JVM parameter configuration.

  • Step 6: Find the most appropriate parameters, apply them to all servers, and follow up.

JVM tuning important parameter parsing

Note: The optimal JVM stability parameter configuration varies from application to application.

Configuration:

-server

-Xms12g -Xmx12g -XX:PermSize=500m -XX:MaxPermSize=1000m -Xmn2400m -XX:SurvivorRatio=1 -Xss512k -XX:MaxDirectMemorySize=1G

-XX:+DisableExplicitGC -XX:CompileThreshold=8000 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

-XX:+UseCompressedOops -XX:CMSInitiatingOccupancyFraction=60 -XX:ConcGCThreads=4

-XX:MaxTenuringThreshold=10 -XX:ParallelGCThreads=8

-XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled

-XX:CMSMaxAbortablePrecleanTime=500 -XX:CMSFullGCsBeforeCompaction=4

XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection

-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/weblogic/gc/gc_$$.log

Copy the code

Important parameters (adjustable)

-Xms12g: initialize the heap memory size to 12GB. -xmx12g: the maximum heap memory is 12GB. -Xmn2400m: the new generation size is 2400MB, including Eden zone and two Survivor zones. -xx :SurvivorRatio=1: The ratio of Eden zone and Survivor zone is 1:1. -xx :MaxDirectMemorySize=1 GB: direct memory. The Java. Lang. OutOfMemoryError: Direct buffer memory exceptions can increase this value. -xx :+DisableExplicitGC: Disables explicit calls to System.gc() at run time to trigger fulll GC. Note: the timing of Java RMI GC triggering mechanism can be configured - Dsun. RMI. DGC. Server gcInterval = 86400 to control the trigger time. - XX: CMSInitiatingOccupancyFraction = 60: recycling old s memory threshold, the default value is 68. -xx :ConcGCThreads=4: CMS garbage collector parallel threads. The recommended value is the number of CPU cores. -xx :ParallelGCThreads=8: Indicates the number of threads of the new-generation parallel collector. -xx :MaxTenuringThreshold=10: Sets the maximum age of garbage. If set to 0, the young generation object enters the old generation without passing through Survivor. For applications with more aged generations, efficiency can be improved. If this value is set to a large value, the young generation object will be copied multiple times in the Survivor area, which increases the lifetime of the object in the next young generation and increases the probability that the object will be reclaimed in the young generation. - XX: CMSFullGCsBeforeCompaction = 4: specify how many times after fullGC, tenured area memory space compression. - XX: CMSMaxAbortablePrecleanTime = 500: when abortable - preclean pre-cleaning stage performing at this time will be over.Copy the code

Scenarios that trigger Full GC and corresponding countermeasures

The collection of the young generation (including the Eden and Survivor fields) is called the Minor GC, the old GC is called MajorGC, and the Full GC is for the entire heap. In recent versions of the JDK, the default collection of the immortal band is the method area (there is no immortal band in JDK8). A Full GC is usually accompanied by at least one Minor GC, but not always. MajorGC is typically more than 10 times slower than Minor GC.

Scenarios for triggering Full GC and countermeasures:

  1. -xx :+DisableExplicitGC to disable calls to system.gc;

  2. The space of the elderly generation is insufficient. The coping strategy is to collect the objects in the Minor GC phase and keep the objects alive for a while. Do not create too large objects and arrays.

  3. The space of the immortal zone is insufficient. The coping strategy is to increase the space of PermGen

  4. If promotionFailed and concurrent mode failure occur during GC, the solution is to increase survivor space

  5. Promotion to the old generation born after Minor GC object size is greater than the old s of the remaining space, coping strategies: increase the Tenured space or cut CMSInitiatingOccupancyFraction = 60

  6. Full GC occurs due to memory growth. Use DumpheAP to analyze whether memory leaks exist

Gc log analysis tool

With the GCViewer log analysis tool, you can intuitively analyze the pending benefits.

It can be analyzed from the following aspects:

  1. Memory: Analyze the Memory usage of Totalheap, Tenuredheap, Youngheap, and other indicators. Theoretically, the smaller the Memory usage, the better.

  2. Pause: Analyzes each indicator of Gc Pause, Fullgc Pause, and Total Pause. Theoretically, the fewer THE Gc times, the better. The shorter the Gc duration, the better.