It's been 2014 years now, but for most developers there are two things that are still a mystery--java garbage collection and the opposite sex (the yards were laughed at again). Since I don't know much about the latter, I think I'll try to talk about the former, especially with the advent of Java8, where there have been significant changes and improvements, the most important of which is the removal of persistent generations (PermGen) and some exciting new optimizations (which are mentioned later). Talking about garbage collection, many people understand its concept, but also in the daily programming of the application. Still, there are many things that we don't know very well, and that's the root of the pain. The biggest misconception about the JVM is that it has only one garbage collector, and in fact it has four different recyclers, each with its own length. The JVM does not automatically select one, and it falls on you and me because different recyclers bring significant differences in throughput and pause times for applications. The common thing about these four recycling algorithms is that they are all generational, meaning that they divide the managed heap into several regions, assuming that many objects in the heap have a short life cycle and can be quickly recycled. The introduction of this piece of content has been many, so I am going to talk about these several different algorithms, and their strengths and weaknesses. 1. Serial CollectorThe serial collector is the simplest one, and you will not consider using it because it is primarily for single-threaded environments (such as 32-bit or windows) and smaller heaps. When this collector works, it freezes all application threads, which makes it completely impossible for the server to use. How to use it: You can open-XX:+USESERIALGC this JVM parameter to use it. 2. Parallel/Throughput CollectorNext is the parallel collector (Parallel collector). This is the default garbage collector for the JVM. As its name says, its greatest advantage is that it uses multiple threads to scan and compress the heap. Its disadvantage is that it suspends the application thread regardless of whether it is executing a minor GC or full GC. The parallel collector is best suited for applications that can tolerate pauses, and it attempts to reduce the CPU overhead caused by the collector. 3.CMS Recycle CollectorThe parallel collector is followed by the CMS collector (concurrent-mark-sweep). The algorithm uses multiple threads (concurrent) to scan the heap and mark (Mark) objects that can be recycled (sweep) that are no longer in use. This algorithm enters a "Stop the world" pattern in two cases: when the initial tag of the root object is (The Laosheng of the thread entry point or the static variable) and when the algorithm is running concurrently, the application changes the state of the heap so that it has to go back and confirm that the object it is tagging is correct. The biggest problem with using this collector is that you will encounter promotion failure, which refers to the conditions of competition when recovering from the new generation and old age. If the collector needs to raise the young object to the old age, and there is no extra space for the old generation, it can only start with the full GC of the STW (Stop the World)-a situation that the CMS would like to avoid. To ensure that this does not happen, you either increase the size of the Laosheng (or increase the size of the entire heap) or allocate some background threads to the collector to race against the speed at which the objects are allocated. Another disadvantage of this algorithm is that it uses more CPU resources than the parallel collector, which uses multiple threads to perform scanning and recycling, so that the application continues to provide higher levels of throughput. For most long-running programs, application pauses are bad for them, and you can consider using a CMS collector at this time. However, this algorithm is not enabled by default. You have to specify XX:+USECONCMARKSWEEPGC to enable it. Assuming your heap is less than 4G and you want to allocate more CPU resources to avoid app pauses, this is the collector you want to choose. However, if the heap is larger than 4G, you might prefer to use the last--G1 collector. 4.G1 Recycle CollectorFirst introduced in JDK 7update 4, the G1 (garbage) collector is designed to better support heaps larger than 4GB. The G1 collector divides the heap into multiple areas, ranging in size from 1MB to 32MB, and uses multiple background threads to scan them. The G1 collector prioritizes the areas that contain the most rubbish, which is the origin of its name (garbage first). This collector can be enabled with the-XX:USEG1GC tag. This strategy reduces the likelihood that the heap will be exhausted before the background thread has scanned the unused objects, and that the garbage collector has to suspend the application, which can lead to STW recycling. Another benefit of G1 is that it will always compress the heap, and the CMS collector will only do this when the full GC is in place. Over the past few years, the heap has been a controversial area, with many developers moving from single-machine single-JVM models to single-machine, multi-JVM microservices, and modular architectures. This is driven by a number of factors, including components for isolating programs, simplifying deployment, and avoiding the overhead of reloading application classes to memory (this has been improved in Java 8). Still, the main thing to do is to avoid a long period of "Stop the World" pauses in a large heap of GC (which takes a few seconds to complete in a large collection). Container technology like Docker also accelerates this process, making it easy to deploy multiple applications on the same physical machine. Java 8 and G1 CollectorA great optimization introduced in Java 8 update 20 is the string G1 (string deduplication) in the garbage collector. Because strings (including their internal char[] arrays) occupy most of the heap space, this new optimization is designed to enable the G1 collector to identify the duplicated strings in the heap and point them to the same internal char[] array to avoid multiple copies of the same string. The efficiency of the heap will become very low. You can use the-xx:+usestringdeduplication JVM parameter to try this feature. Java 8 and persistent generationsThe biggest change in Java 8 is the removal of persistent generations, which was originally used to allocate space for class metadata, resident strings, and static variables. This has previously required developers to specialize in heap scale optimization and tuning for applications that load a large number of classes. This has been the case for many years, and this is the source of many outofmemory anomalies, so it is never too bad for the JVM to take over. Even so, it does not in itself reduce the likelihood that developers will decouple the application into different JVMs. Each collector has many different switches and options to tune, which may increase throughput or may decrease, depending on the specific behavior of your application. In the next article we'll dive into the key strategies for configuring these algorithms. |