Preface
CMS, full name concurrent low Pause Collector, is a new GC algorithm introduced by the jdk1.4 later version, which has been further improved in Jdk5 and JDK6, and its main fit scenario is that the need for response time is greater than the throughput requirements. The ability to tolerate garbage collection threads and application threads to share processor resources, and to apply applications where there are more long-life-cycle objects. CMS is used to recycle tenured generation, which is the recycling of older generations, with the goal of minimizing application pauses, reducing the chance of full GC occurrences, and using garbage collection threads that are associated with the application thread to clear older generations. In our application, because of the presence of the cache and the high demand for response time, we would like to try to use a CMS instead of the parallel collector used by the default server JVM in order to get a shorter garbage collection pause time and improve the responsiveness of the program.
CMS Collection Cycle
Instead of pausing, the CMS replaces the long pause of the serial tagging algorithm with two short pauses, and the collection period is this:
Concurrent Cleanup (cms-concurrent-sweep), re-tagging (cms-remark), concurrent tagging (cms-concurrent-mark), initial tag (Cms-initial-mark) Concurrent reset status waits for the next CMS trigger (Cms-concurrent-reset).
Of these, 1, 32 steps need to be paused for all application threads. The first pause marks the surviving object from the root object, which is called the initial tag, and the second pause is after the concurrency token, pausing all application threads, and re-tagging the objects that were omitted from the concurrency tag phase (the update of the object state after the concurrency tagging phase ended). The first pause is shorter, the second pause is usually longer, and the remark phase can be marked in parallel.
The so-called concurrency of concurrent tagging, concurrent purging, and concurrent reset is that one or more garbage collection threads and application threads run concurrently, the garbage collection thread does not halt the execution of the application, and if you have more than one processor, the concurrent collection thread will run on a different processor than the application thread, apparently This overhead can reduce the throughput of your application. Remark phase parallelism means that when all applications are paused, a certain number of garbage collection processes are started for parallel tagging, at which point the application thread is paused.
The recovery of the CMS's young generation is still a parallel copy collector, which is consistent with the Paralle GC algorithm.
Parameter Introduction
1, enable CMS:-XX:+USECONCMARKSWEEPGC.
2. The number of recycle threads that the CMS starts by default is (Parallelgcthreads + 3)/4), and if you need to explicitly set it, you can set it by-xx:parallelcmsthreads=20. Where Parallelgcthreads is the number of parallel collection threads for young generations
3, CMS will not defragment the heap, so in order to prevent heap fragmentation caused by full GC, by opening the CMS phase of the merge fragmentation option:-xx:+usecmscompactatfullcollection, opening this option to some extent will affect performance, PO's blog said it may be possible to configure the appropriate cmsfullgcsbeforecompaction to adjust performance, not practice.
4. To reduce the time of the second pause, turn on parallel remark:-xx:+cmsparallelremarkenabled. If the remark is too long, you can turn on the-xx:+cmsscavengebeforeremark option, force remark to start a minor GC before, reduce the remark pause time, However, after remark, you will also start minor GC again immediately.
5. To avoid full GC caused by Perm, it is recommended to turn on the CMS recycle perm zone option:
+cmspermgensweepingenabled-xx:+cmsclassunloadingenabled
6. The default CMS is to start the CMS collection when the tenured generation is stained with 68%, if your old generation growth is not so fast, and you want to reduce the number of CMS, you can adjust this value appropriately:
-xx:cmsinitiatingoccupancyfraction=80
It changed to 80% when it was stained with the start of CMS recycling.
7. The number of parallel collection threads for young generations is (CPU <= 8) by default? Cpu:3 + ((CPU * 5)/8), if you want to reduce the number of threads, you can adjust by-xx:parallelgcthreads= N.
8. Enter the focus, after the initial set of some parameters, such as:
It is necessary to measure the performance of the system under these parameters in a production environment or in a pressure measurement environment, when the GC log is opened to view the specific information, so add the parameters:
-verbose:gc-xx:+printgctimestamps-xx:+printgcdetails-xloggc:/home/test/logs/gc.log
To view the performance of the CMS over a long period of time, the CMS log output is similar to this:
4391.322: [GC [1 cms-initial-mark:655374k (1310720K)] 662197K (1546688K), 0.0303050 secs] [times:user=0.02 sys=0.02, Real =0.03 secs] 4391.352: [Cms-concurrent-mark-start] 4391.779: [cms-concurrent-mark:0.427/0.427 secs] [times:user=1.24 sys=0.31, real=0.42 secs] 4391.779: [Cms-concurrent-preclean-start] 4391.821: [cms-concurrent-preclean:0.040/0.042 secs] [times:user=0.13 sys=0.03, real=0.05 secs] 4391.821: [Cms-concurrent-abortable-preclean-start] 4392.511: [ cms-concurrent-abortable-preclean:0.349/0.690 secs] [times:user=2.02 sys=0.51, real=0.69 secs] 4392.516: [GC[YG occupancy:111001 K (235968 k)]4392.516: [Rescan (parallel), 0.0309960 secs]4392.547: [Weak refs processing, 0.0417710 SE CS] [1 cms-remark:655734k (1310720K)] 766736K (1546688K), 0.0932010 secs] [times:user=0.17 sys=0.00, real=0.09 secs] 4392. 609: [Cms-concurrent-sweep-start] 4394.310: [cms-concurrent-sweep:1.595/1.701 secs] [times:user=4.78 sys=1.05, real= 1.70 secs] 4394.310: [Cms-concurrent-reset-start] 4394.3: [cms-concurrent-reset:0.054/0.054 secs] [times:user=0.14 sys=0.06, real=0.06 secs]
One can see that the Cms-initial-mark phase is paused for 0.0303050 seconds, while the Cms-remark phase pauses for 0.0932010 seconds, so the total time for two pauses is 0.123506 seconds, or about 123 milliseconds. The sum of two short stops can be referred to as normal under 200.
But you are likely to encounter two kinds of fail caused by full gc:prommotion failed and concurrent mode failed.
The log output of the prommotion failed is probably this:
The problem arises from the fact that there is not enough space in the rescue to transfer objects to older generations, and that older generations do not have enough space to accommodate these objects, resulting in a full GC. The solution to this problem has two completely opposite tendencies: to increase the space for salvation, to increase the age of older generations, or to remove the relief space. Increase the rescue space is to adjust the-xx:survivorratio parameter, this parameter is the size ratio of Eden and Survivor area, the default is 32, that is, Eden area is the survivor area of 32 times times the size, pay attention to Survivo is two zones, So Surivivor actually accounted for 1/34 of all young genertation. This parameter will increase the survivor area, so that the object as far as possible in the Survitor area to stay a little longer, to reduce the age of the object. The idea of getting rid of the rescue space is to get most of the data that cannot be recovered quickly into the old generation, to speed up the recovery of older generations and to reduce the likelihood of an old generation soaring, by setting-xx:survivorratio to a larger value (such as 65536). In our application, the young generation set to 256M, this value is relatively large, and the rescue space is set to the default size (1/34), from the pressure measurement situation, there is no prommotion failed phenomenon, the younger generation is relatively large, from the GC log view, The time of the minor GC is also acceptable in 5-20 milliseconds, so it is temporarily not adjusted.
Concurrent mode failed is due to the recovery of the old age of the CMS is too slow, resulting in the old generation in the CMS before the completion of being stained, causing the full GC, to avoid this phenomenon is to adjust the small-xx: The value of the Cmsinitiatingoccupancyfraction parameter allows the CMS to trigger earlier and more frequently, reducing the likelihood that older generations will be stained. Our application has a low temporary load, and the growth of older generations is very slow in the production environment, so this parameter is temporarily set to 80. In the pressure measurement environment, the performance of this parameter can also, did not appear concurrent mode failed.
JVM GC Algorithm CMS detailed (GO)