I originally wanted to set the question as "don't stop", but I still want to do it by YY.
The biggest obstacle to Java Development Server is that the serial garbage collection mechanism before JDK will cause a long service suspension. After understanding the principle, think about the predecessors who wrote the server with JDK and have to fear it later.
Fortunately, jdk1.4 has started to support multi-thread parallel background garbage collection algorithms, while jdk5.0 has optimized the default value settings.
I. References:
- Tuning Garbage Collection with the 5.0 Java Virtual Machine official guide.
- Hotspot memory management whitepaper White Paper.
- Java Tuning White Paper official documentation.
- FAQ about Garbage Collection in the Hotspot FAQ, JVM1.4.2.
- Java HotSpot Virtual Machine garbage collection Chinese ppt on JavaOne2004
- A Collection of JVM Options JVM option ultra-Complete Collection.
Ii. Basic Concepts
1. Heap)
The memory managed by JVM is called heap. The 32-bit operating system has the limit of 1 GB to 2 GB, but 64 bit does not.
The memory initially allocated by JVM is specified by-XMS. The default value is 1/64 of the physical memory but less than 1 GB.
The maximum memory allocated by JVM is specified by-xmx. The default value is 1/4 of the physical memory but less than 1 GB.
By default, when the free heap memory is less than 40%, the JVM will increase the heap until the maximum limit of-xmx can be specified by-XX: minheapfreeratio =.
By default, when the free heap memory is greater than 70%, the JVM will reduce the minimum heap limit to-XMS, which can be specified by-XX: maxheapfreeratio =.
Generally, the server sets-XMS and-xmx to be equal to each other to avoid adjusting the heap size after each GC. Therefore, the above two parameters are useless.
2. Basic Collection Algorithms
- Copy: Divide the heap into two identical spaces, access each associated active object from the root (ThreadLocal object, static object), and copy all the active objects of space A to Space B, then, the whole space A is reclaimed at one time.
Because only active objects are accessed, the whole space is cleared after all active objects are copied, and no dead objects are accessed. Therefore, the cost of traversing the space is small, however, it requires a huge copy cost and a large amount of memory.
- Mark-sweep ):The collector first accesses all active objects from the root and marks them as active objects. Then, traverse the entire memory area and recycle all unmarked objects. The cost of traversing the entire space is large. The pause time increases linearly with the size of the space, and there are a lot of fragments in the heap after sorting.
- Mark-sweep-compact ):Based on the practices and advantages of the two, the system first marks the active object and combines it into a large memory block.
It can be seen that there is no free lunch, whether using the copy or mark clearing algorithm, automatic things will have to pay a lot of performance costs.
3. Generation Division
Generational collection is a highlight of Java garbage collection. Based on the length of the object's lifecycle, the heap is divided into three generations: Young, Old, and Permanent, different collection algorithms are used based on the characteristics of different generations, so as to foster strengths and circumvent weaknesses.
Young (Nursery), Young Generation. Research shows that most objects are dying and dying. Therefore, all collectors select the replication algorithm for the young generation.
The advantage of the replication algorithm is that it only accesses active objects, but the disadvantage is that the replication cost is high. Because only a small number of objects in the young generation can be collected by garbage collection, there is only a small copy cost. In addition, the replication collector only accesses active objects and turns a blind eye to the Dead objects that account for the largest proportion, giving full play to its advantages of low space traversal costs.
The default value of Young is 4 MB, which is about 1/15 as the heap memory increases. The JVM dynamically manages the size change as needed.
-XX: The NewRatio = parameter can be used to set the size ratio of Young to Old. The default value of-server is, but is it much lower than the ratio of young at startup? If you cannot trust the JVM, you can use-Xmn to specify its size. We recommend that you set it to 1/4 of the total Heap size.
The size of Young is very important. For more information, see "Pause Time First Collector.
Young is divided into three areas, One Eden, where all new objects exist and two vor regions are used to implement the replication algorithm. Each copy is to copy the live objects of Eden and the first primary or to 2nd, and then clear the Eden and the first primary or. The ratio of Eden to primary VOR is set from-XX: Primary vorratio =. The default value is 32. When vio is too large, it will be a waste. If it is too small, it will cause some young objects to flee to the elderly area, causing anxiety in the elderly area. However, this parameter is not important to performance.
Old (Tenured), aged. If the objects of the young generation can be collected several times, they will enter the elderly area. The elderly area uses the tag sorting algorithm. Because the objects in the elderly area are not so easy to die, it is necessary to repeatedly copy objects by using the replication algorithm, which is not cost-effective. We have to use the mark clearing algorithm, but the mark clearing algorithm is not easy, every time you traverse all objects in the area, there is still no free lunch.
-XX: MaxTenuringThreshold = sets the number of times the young generation has been collected and moved into the old area. The default value of CMS is 0. After the first GC, it is transferred. You can use-XX: + PrintTenuringDistribution to view it.
Permanent, Permanent generation.The default value for loading basic data such as Class information is 64 mb. If it is a service program with many classes, you need to increase the setting-XX: MaxPermSize =; otherwise, fullgc () will occur when it is full () or Out of Memory. Note that frameworks like Spring and Hibernate that like the dynamic generation of AOP require more persistent generation memory.
4. minor/major collection
When each generation is full, collection will be promoted. (In addition, Concurrent Low Pause Collector is promoted by default when the Community is 68% ). GC scans and recycles young at a high frequency, which is called minor collection..
Because of the cost relationship, the Old check recovery frequency is much lower, and the collection of Young and Old is called major collection.
System. gc () will trigger the major collection and disable it using-XX: + DisableExplicitGC, or set it to CMS concurrency-XX: + ExplicitGCInvokesConcurrent.
5. Summary
Young -- minor collection -- Copy Algorithm
Old (Tenured) -- major colletion -- tag clearing/Tag Sorting Algorithm
Iii. Collectors
1. The ancient Serial Collector)
The-XX: + UseSerialGC policy is used for serial replication of the young generation and serial marking of the old generation.
2. Throughput-first parallel Collector (Throughput Collector)
Use-XX: + UseParallelGC, which is also the default value of JDK 5-server. Policy:
1. The young generation suspends the application. Multiple garbage collection threads are used for parallel replication and collection. The number of threads is the number of CPUs by default. When there are many CPUs,-XX: ParallelGCThreads = reduces the number of threads.
2. The application is suspended in the old generation. Like the serial collector, a single garbage collection thread is marked for sorting.
Therefore, a 2 + CPU is better than the serial collector, which is suitable for background processing and scientific computing.
You can use-XX: MaxGCPauseMillis = and-XX: GCTimeRatio to adjust the GC time.
3. Pause the time-first Concurrent Collector (Concurrent Low Pause Collector-CMS)
As mentioned above, we have paved the way for this section ......
Use-XX: + UseConcMarkSweepGC. The policy is as follows:
1. The young generation also suspends applications and multiple garbage collection threads concurrently copy and collect data.
2. The old generation only has two short pauses, and applications and collection threads are concurrently cleared at other times.
3.1 elder generation details
Parallelism is only one word different from Concurrent. parallelism refers to the Parallel processing of multiple garbage collection threads. Concurrency refers to the concurrency between the user thread and the garbage collection thread, and the program continues to run, the garbage collection program runs on another CPU.
At the beginning of concurrent collection, all threads will be stopped for a short time to start marking the root object, and then marking the concurrent running of the thread and the application thread. Finally, the thread will be paused for a short time.ParallelRe-mark the objects that may be missed due to concurrency, and then begin to clear the process of concurrency with the application. It can be seen that the longest two traversal processes are executed concurrently with the application, which is too much improved than the previous Serial Algorithm !!!
Serial mark clearing starts collection when the old generation is full. Concurrent collection is performed because it is run with the application. If the collection is full, the application has no memory available, therefore, the system starts collection when 68% is full by default. The memory has been set to a large size. When the memory consumption is not so fast, you can use-XX: CMSInitiatingOccupancyFraction = to increase the ratio appropriately.
3.2 young generation details
Unfortunately, for the replication and collection of the young generation, all application threads must be stopped. In this way, the collection speed can only be improved by multiple CPUs and multiple collection threads concurrently, however, unless your Server exclusively occupies the entire Server, if there are many other threads on the Server, the switching speed will be ..... so, at the end, the bottleneck of the pause time falls on the replication algorithm of the young generation.
Therefore, the size setting of Young is very important, so frequent GC is not required when it is large, and after increasing the GC interval, the multi-point object can die on its own without copying. However, when Young increases, the pause time caused by GC is very scary. For example, on my machine, the default 8 m Young takes only a few milliseconds, and 64 m increases to 90 ms, when it reaches 300 m, it will take 800 ms, and the peak will reach ms. Who is the replication algorithm? When Young is full, the collection starts. When the collection starts, it is necessary to stop all threads.
3.3 permanent generation
-XX: + CMSClassUnloadingEnabled-XX: + CMSPermGenSweepingEnabled, which enables CMS to collect persistent generation classes instead of fullgc, netbeans5.5 performance documentation recommendations.
4. Incremental (train algorithm) Collector (Incremental Collector)
Maintenance is stopped. The-Xincgc option is converted to the concurrent collector by default.
Iv. Pause Time Display
Add the following parameters (remove spaces in the middle of PrintGC and Details. CSDN considers it a ban)
-Verbose: gc-XX: + PrintGC Details-XX: + PrintGCTimeStamps
The following output is displayed when the program is running.
9.211: [GC 9.211: [ParNew: 7994 K-> 0 K (8128 K), 0.0123935 secs] 427172 K-> 419977 K (524224 K), 0.0125728 secs]
It is shown that Minor garbage collection occurs in the first 9.211 seconds of the program running. The previous data is collected from 8128 kb to 0 kb for the new area, and the total size of the new area is kb, the program paused for 12 ms, and the next piece of data targeted the entire heap.
For the collection of older generations, the pause occurs in the following two phases, and the interruption of CMS-remark is 17 milliseconds:
[GC [1 CMS-initial-mark: 80168 K (196608 K)] 81144 K (261184 K), 0.0059036 secs]
[1 CMS-remark: 80168 K (196608 K)] 82493 K (261184 K), 0.0168943 secs]
Add two parameters-XX: + PrintGCApplicationConcurrentTime-XX: + PrintGCApplicationStoppedTime to make the pause time clearer.
5. Truly uninterrupted BEA JRockit and Sun RTS2.0
One of the features of Bea's JRockit 5.0 R27 is a dynamically determined garbage collection policy. Users can decide whether they are concerned with throughput, pause time, or a specific pause time, the JVM dynamically decides and changes the garbage collection policy at runtime.
Its Deterministic GC option is-Xgcprio: deterministic. It is said that the pause can be controlled in 10-30 milliseconds, which is very good. A Deterministic statement is the true meaning of RealTime. But take a closer look at the document. The 30 ms test environment is 1 GB heap and an average of 30% active objects (that is, 300 M), 2 Xeon 3.6 GHz 4G memory, or 4 Xeon 2.0 GHz, 8 GB memory.
It is a pity that the license of JRockt is very strange. Although it is usually used for free, but this 30 ms option requires the purchase of the license of the entire Weblogic Real Time Server.
Other free options include:
- -Xgcprio: pausetime-Xpausetarget = 210 ms
Because it is free of charge, you can only set it to 200 ms pause target. Ms is the dividing line that Sun considers as Real-Time.
- -Xgc: gencon
The efficiency is also good with common concurrency practices.
Java one2007 introduced Sun's Java Real-Time System 2.0. Based on JDK1.5, RTS2.0 has improved its Real-Time Garbage Collctor. However, it is still in beta status and only available to OEMs, more strange.
Vi. Improvements to JDK 6.0
Because JDK5.0 was not satisfactory when Young was large, he continued to look at improvements made by JDK6.0. The results were a little disappointing and did not involve the improvement of the replica collection of my most headache for Young generation.
1. Old generation identification-clear collection and execute identification in parallel
JDK 6.0 only enables a collection process and application thread concurrent identification, while can enable multiple collection threads for identification, shortening the time to identify all active objects in the elderly area.
2. Increase the default size of the Young area.
The default size is increased from 4 MB to 16 MB, and from 1/15 of heap memory to 1/7.
3. System. gc () can be executed concurrently with the application.
Use-XX: + ExplicitGCInvokesConcurrent to set
VII. Summary
1. JDK5.0/6.0
For server applications, we use Concurrent Low Pause Collector to collect parallel multi-thread replication during Pause for the young generation; for the old generation, the Collector and the application are marked in parallel -- sort and collect, to minimize the garbage collection time.
In the spirit of not optimizing without a thorough test, the command line attribute can be simply written:
-Server-XMS M-xmx M-XX: + useconcmarksweepgc-XX: + printgc details-XX: + printgctimestamps
Then, based on the application situation, you can check if there are JVM default values and auto-management is not enough, such as-xmn to set the size of Young,-XX: maxPermSize sets the persistent generation size.
2. jrock it 6.0 R27.2
However, the JDK5 test results were not satisfactory, and later I tried JRockit, and the overall effect was better.
JRockit is characterized by the dynamic Garbage Collector dynamically determines the collection algorithm based on the characteristics of the user's interest. The parameters are as follows:
-XMS M-xmx M-xgcprio: pausetime-xpausetarget = 200 ms-xgcreport-xgcpause-xverbose: Memory