Detailed explanation of JVM tuning parameters

There are two types of GC: Scavenge GC and Full GC
1. Scavenge GC
   In general, when a new object is generated and fails to apply for space in Eden, Scavenge GC will be triggered, the Eden area of ​​the heap will be GCed, and non-surviving objects will be cleared. And move the surviving objects to the Survivor's two areas.
2. Full GC
   organizes the entire heap, including Young, Tenured, and Perm. Full GC is slower than Scavenge GC, so you should reduce Full GC as much as possible. The following reasons may cause Full GC
   a and Tenured to be full;
   b, Perm field is full
   c, System.gc() is displayed and called
   d, above The allocation strategy of each domain of Heap changes dynamically after a GC;


-Xmx512m -Xms512m -Xmn192m -Xss128k

The maximum heap size in the JVM is limited by three aspects, the data model (32-bit or 64-bit) of the relevant operating system; the available virtual memory of the system Limit; the system's available physical memory limit
-Xmx512m:
   Set the maximum available memory of the JVM instance heap to 512M.
-Xms512m:
   Set the JVM to promote memory to 512m. This value can be set the same as -Xmx to avoid reallocation of memory by the JVM after each garbage collection is complete.
-Xmn192m
   Set the young generation size to 192m. The entire JVM memory size = young generation size + old generation size + persistent generation size. The persistent generation is generally fixed at 64m, so after increasing the young generation, the size of the old generation will be reduced. This value has a great impact on system performance, and Sun officially recommends setting it to 3/8 of the entire heap.
-Xss128k
   sets the stack size per thread. After JDK5.0, the stack size of each thread is 1M, and the previous stack size of each thread is 256K. Adjust the memory size required by the threads of the application. In the same physical memory, reducing this value can generate more threads. However, the operating system still has a limit on the number of threads in a process, which cannot be generated indefinitely, and the experience value is around 3000~5000.

Pay attention to the following problems:     
(1) Although increasing the size of Heap will reduce the frequency of GC, it will also increase the time of each GC. And while the GC is running, all user threads will be suspended, that is, the Java application will not do any work during the GC.
(2) Heap size does not determine the memory usage of the process. The memory usage of a process is larger than the value defined by -Xmx because Java allocates memory for other tasks, such as stacks per thread, etc.  
(3) It is better for the JVM on the server side to set -Xms and -Xmx to the same value. In order to optimize the GC, it is best to make the value of -Xmn equal to about 1/3 of -Xmx (it is also pointed out as 3/8).
(4) An application should preferably run a GC every 10 to 20 seconds, each time completing within half a second.

java -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
-XX:NewRatio=4
   Set the ratio of young generation (including Eden and two Survivor regions) to old generation (excluding persistent generation). If set to 4, the ratio of the young generation to the old generation is 1:4, and the young generation accounts for 1/5 of the entire stack.
-XX:SurvivorRatio=4
   Sets the size ratio of the Eden area to the Survivor area in the young generation. Set to 4, the ratio of two Survivor areas to one Eden area is 2:4, and one Survivor area accounts for 1/6 of the entire young generation

-XX:PermSize=128M
   Set the persistent generation size to 128M
-XX:MaxPermSize=16m
   set The persistent generation is up to 16m.
     If MaxPermSize is too small, it will cause: java.lang.OutOfMemoryError: PermGen space 

-XX:MaxTenuringThreshold=0
    to set the maximum age of garbage. If it is set to 0, the young generation objects directly enter the old generation without passing through the Survivor area. For applications with a large number of old generations, the efficiency can be improved. If this value is set to a larger value, the young generation object will be replicated multiple times in the Survivor area, which can increase the survival time of the object in the young generation and increase the generalization that it will be recycled in the young generation.


The JVM gives three options: the
   serial collector
      uses a single thread to handle all garbage collection work, because it does not require multi-threaded interaction, so it is more efficient, but it cannot use the advantages of multiple processors, so this collector uses a single-processor machine . Of course, this collector can also be used on multiprocessor machines with small data volume (100M), which can be opened with -XX:+UseSericalGC

      Applicable situation: The amount of data is relatively small (about 100M); applications that do not require the corresponding time under a single processor
      Disadvantages: can only be used for small applications
   The parallel collector
       performs parallel garbage collection on the young generation, so it can reduce the garbage collection time, Typically used on multithreaded machines. Enhanced in Java SE6.0, parallel collection can be performed in the old generation. If the old generation does not use concurrent collection, single-threaded garbage collection is used, so it will restrict the expansion ability. Use -XX:+UserParallelOldGC to

       open- XX:ParallelGCThreads=N, set the number of threads for parallel garbage collection, this value can be set to be consistent with the number of machine processors;

       usage: "high throughput requirements", multi-CPU, medium and large applications that do not require application time . Such as background processing and scientific computing
       Disadvantages: the corresponding time of the application may be long; the
   concurrent collector
       can ensure that most of the work is performed concurrently (the application does not stop), and the garbage collection is only suspended for a small time. This collector is suitable for the corresponding time requirements. High medium and large scale applications.
       Use -XX:+UseGoncMarkSweepGC to open the

       applicable situation: "high requirements for response time", multi-CPU, medium and large applications that have high requirements for application response time. Such as: Web server/application server, telecom exchange, integrated development environment,

but serial collector is only suitable for small data volume, so the choice here is mainly for parallel collector and concurrent collector.
   By default, JDK5.0 used to use serial collectors. If you want to use other collectors, you need to add corresponding parameters at startup. After JDK5.0, the JVM will judge according to the current system configuration.

Throughput-first parallel collectors
   As mentioned above, parallel collectors mainly aim to achieve a certain throughput, and are suitable for science and technology and background processing.
Typical configuration:
java -Xmx3800m -Xms3800m -Xmn192m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20
-XX:+UseParallelGC
   selects the garbage collector as the parallel collector. This configuration is only valid for the young generation. That is, under the above configuration, the young generation uses concurrent collection, while the old generation still uses serial collection.
-XX:ParallelGCThreads=20
   configures the number of threads of the parallel collector, that is, how many threads perform garbage collection together at the same time. This value is best configured to be equal to the number of processors.
java -Xmx512m -Xms512m -Xmn192m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC
-XX:+UseParallelOldGC
    configures the old generation garbage collection method as parallel collection. JDK6.0 supports parallel collection of the old generation.
java -Xmx512m -Xms512m -Xmn192m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100
-XX:MaxGCPauseMillis=100
    Set the maximum time for each young generation garbage collection. If this time cannot be met, the JVM will automatically adjust the young generation size to satisfy this value.
    If this value is specified, the heap size and garbage collection related parameters will be adjusted to reach the specified value, setting resign may reduce the throughput of the application.
java -Xmx512m -Xms512m -Xmn192m -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy
-XX:+UseAdaptiveSizePolicy After
   setting this option, the parallel collector will automatically select the young generation area size and the corresponding survivor area It is recommended to keep this value open when using the parallel collector.
-XX:GCTimeRatio=n: Set the percentage of garbage collection time to program running time. The formula is 1/(1+n)
  throughput, which is the ratio of garbage collection time to non-garbage collection time. When -XX:GCTimeRatio=19, it means that 5% of the time is used for garbage collection. The default is 99, that is, 1% of the time is used for garbage collection. Parallel collector with priority in


response time
As mentioned above, the concurrent collector is mainly to ensure the system response time, reducing the pause time during garbage collection. Applicable to application servers, telecommunication fields, etc.
Typical configuration:
java -Xmx512m -Xms512m -Xmn192m -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
    Set the old generation for concurrent collection. After configuring this in the test, the configuration of -XX:NewRatio=4 is invalid for unknown reasons. Therefore, the young generation size is best set with -Xmn at this time.
-XX:+UseParNewGC
    sets the young generation for parallel collection. Can be used concurrently with CMS collection. Above JDK5.0, the JVM will set itself according to the system configuration, so there is no need to set this value.
java -Xmx512m -Xms512m -Xmn192m -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction
   Because the concurrent collector does not compress and organize the memory space, it will generate "fragmentation" after running for a period of time ”, which reduces the operating efficiency. This value sets how many times to compress and organize the memory space after running GC.
-XX:+UseCMSCompactAtFullCollection
    turns on compression for the old generation. May affect performance, but can eliminate fragmentation  



auxiliary information
JVM provides a large number of command line parameters, printing information, for debugging. The main ones are:
-XX:+PrintGC
output form: [GC 118250K->113543K(130112K), 0.0094143 secs]
                [Full GC 121376K->10414K(130112K), 0.0650971 secs]
-XX:+PrintGCDetails
Output format: [GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]
                [GC [DefNew: 8614K->8614K(9088K), 0.00006676K secs] ->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]
-XX:+PrintGCTimeStamps -XX:+PrintGC: PrintGCTimeStamps can be mixed with the above two
Output form: 11.851: [GC 98328K-> 93620K(130112K), 0.0082960 secs]
-XX:+PrintGCApplicationConcurrentTime: Print the uninterrupted execution time of the program before each garbage collection. Can be mixed with the above
Output form: Application time: 0.5291524 seconds
-XX:+PrintGCApplicationStoppedTime: Prints the time the program was paused during garbage collection. Can be mixed with the above
Output form: Total time for which application threads were stopped: 0.0468229 seconds
-XX:PrintHeapAtGC: Print detailed stack information before and after GC   


Common configuration summary
Heap settings
-Xms: Initial heap size
-Xmx: Maximum heap size
-XX:NewSize=n: Set the size of the young generation
-XX:NewRatio=n: Set the ratio of the young generation to the old generation. For example: 3, it means that the ratio of the young generation to the old generation is 1:3, and the young generation accounts for 1/4 of the sum of the old generation and the young generation.
-XX:SurvivorRatio=n: The ratio between the Eden area and the two Survivor areas in the young generation ratio. Note that the Survivor area has two. Such as: 3, it means Eden: Survivor=3:2, a Survivor area occupies 1/5 of the entire young generation
-XX:MaxPermSize=n: Set the persistent generation size
Collector settings -XX:+UseSerialGC :
Set serial collector-
XX:+UseParallelGC:Set Parallel Collector-
XX:+UseParalledlOldGC:Set Parallel Old Generation Collector-
XX:+UseConcMarkSweepGC:Set 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 by the parallel collector for collection. Number of parallel collection threads.
-XX:MaxGCPauseMillis=n: Set the maximum pause time for parallel collection
-XX:GCTimeRatio=n: Set the percentage of garbage collection time to program running time. The formula is 1/(1+n)
concurrent collector settings
-XX:+CMSIncrementalMode: is set to incremental mode. Suitable for single CPU situation.
-XX:ParallelGCThreads=n: Set the number of CPUs used when the young generation collection mode of the concurrent collector is parallel collection. Number of parallel collection threads.


JVM tuning tools Jconsole, jProfile, VisualVM Jconsole
    : JDK comes with it, the function is simple, but it can be used when the system has a certain load. There is a very detailed trace of the garbage collection algorithm.
    JProfiler: Commercial software, requires payment. Powerful.
    VisualVM: JDK comes with powerful functions, similar to JProfiler. Recommendation


Memory leak check
   Memory leak is a relatively common problem, and the solution is also relatively general. Here we can focus on it, and the problems of threads and hot spots are analyzed in detail. Memory leaks can generally be understood as system resources (resources in all aspects, heap, stack, thread, etc.) that are used incorrectly, resulting in the inability to recycle (or not recycle) the used resources, resulting in the inability to complete new resource allocation requests , causing a system error. Memory leaks are more harmful to the system because they can directly lead to system crashes. Need to distinguish, there is a difference between a memory leak and a system overload, although the possible end result is the same. A memory leak is when the used resources are not reclaimed causing an error, while a system overload is when the system really doesn't have that many resources to allocate (other resources are in use).

Tuning Summary
Young Generation Size Selection
Response Time Priority Applications:
      Set it as large as possible until it is close to the minimum response time limit of the system (select it according to the actual situation). In this case, the frequency of young generation collections is also minimal. At the same time, reduce the objects that reach the old generation.
Applications with throughput priority:
      set as large as possible, possibly reaching the level of Gbit. Because there is no requirement for response time, garbage collection can be performed in parallel, which is generally suitable for applications with more than 8 CPUs.
Selection of the size of the old generation
Response time priority applications: The
    old generation uses a concurrent collector, so its size needs to be set carefully, generally considering some parameters such as the concurrent session rate and session duration. If the heap setting is small, it can cause memory fragmentation, high collection frequency and application suspension and use the traditional mark-and-sweep method; if the heap is large, it will take a long time to collect. The optimal solution generally needs to be obtained by referring to the following data:
Concurrent garbage collection information Concurrent collection times of
persistent generation
Traditional GC information The proportion of time
spent on young and old generation collections
Reduce the time spent in young and old generation, generally Improve application efficiency

Throughput -first applications
    Generally throughput-first applications have a large young generation and a small old generation. The reason is that most of the short-term objects can be recycled as much as possible, reducing the medium-term objects, and the old generation can store long-lived objects.
Fragmentation problems caused by smaller heaps
Because old generation concurrent collector uses a mark-and-sweep algorithm, the heap is not compacted. When the collector recycles, it merges adjacent spaces so that they can be allocated to larger objects. However, when the heap space is small, "fragmentation" will occur after running for a period of time. If the concurrent collector cannot find enough space, the concurrent collector will stop, and then use the traditional mark and clear method for recycling. If "fragmentation" occurs, the following configuration may be required:
-XX:+UseCMSCompactAtFullCollection: When using the concurrent collector, enable compression of the old generation.
-XX:CMSFullGCsBeforeCompaction=0: When the above configuration is enabled, how many times of Full GC is set here to compress the old generation

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327077324&siteId=291194637