How a good Java programmer must understand how the GC works

Source: Internet
Author: User
Tags compact scalar java throws

A good Java programmer must understand how the GC works, how to optimize GC performance, and how to interact with the GC in limited ways, because there are applications that have higher performance requirements, such as embedded systems, real-time systems, and so on, which can improve the performance of the entire application only if it improves the management efficiency of the memory completely.

A good Java programmer must understand how the GC works, how to optimize GC performance, and how to interact with the GC in limited ways, because there are applications that have higher performance requirements, such as embedded systems, real-time systems, and so on, which can improve the performance of the entire application only if it improves the management efficiency of the memory completely. This article first briefly introduces how GC works, then discusses several key issues of GC, and finally puts forward some Java programming suggestions to improve the performance of Java program from the point of view of GC.

Fundamentals of GC

Java's memory management is actually the management of objects, including the allocation and release of objects.

For programmers, the allocation object uses the New keyword, and when the object is disposed, whenever an object is assigned a value of NULL, so that the program cannot access the object again, we call the object "unreachable \". The GC will be responsible for reclaiming the memory space of all \ "unreachable \" objects.

For GC, when a programmer creates an object, the GC starts to monitor the object's address, size, and usage. Typically, the GC records and manages all the objects in the heap (see reference 1) in a graph-based manner. In this way, you determine which objects are \ "accessible \" and which objects are \ "unreachable \". When the GC determines that some objects are \ "Unreachable \", it is the GC's responsibility to reclaim these memory spaces. However, in order to ensure that the GC can be implemented on different platforms, the Java specification does not strictly govern many of the GC's behavior. For example, there are no clear rules as to what type of recovery algorithm to use, when to recycle, and so on. Therefore, different JVM implementations often have different implementation algorithms. This also brings a lot of uncertainty to the development of Java programmers. This paper studies several issues related to GC work and tries to reduce the negative impact of this uncertainty on Java programs.

Incremental GC (Incremental GC)

A GC is typically implemented by a process or group of processes in the JVM, which itself consumes heap space as a user program and consumes CPU at runtime. When the GC process runs, the application stops running. Therefore, when the GC is running longer, the user can feel the Java program's pause, on the other hand, if the GC runs too short, the object recovery may be too low, which means that many of the objects that should be recycled are not recycled and still occupy a lot of memory. Therefore, when designing a GC, a tradeoff must be made between the pause time and the recovery rate. A good GC implementation allows the user to define the settings they need, such as some limited memory devices, very sensitive to memory usage, and the hope that the GC can accurately reclaim memory, and it doesn't care about slowing down the program. In addition to some real-time online games, it is not possible to allow long interruptions to the program. Incremental GC is the use of a certain recovery algorithm, a long interruption, divided into a number of small interruptions, in this way to reduce the impact of GC on the user program. Although an incremental GC may not be as efficient as a normal GC in overall performance, it can reduce the maximum downtime of a program.

The HotSpot JVM provided by Sun JDK can support incremental gc.hotspot JVM default GC mode to not use incremental GC, in order to start the Delta GC, we must add-XINCGC parameters when running Java program. The implementation of the HotSpot JVM incremental GC is based on the train GC algorithm. The basic idea is that all objects in the heap are grouped (layered) by creation and usage, with frequently high and relevant objects placed in a single team, and the group is constantly tuned as the program runs. When the GC is running, it always recycles the oldest (recently infrequently accessed) objects, and if the whole group is recyclable, the GC will recycle the whole group. In this way, each GC runs only a certain percentage of unreachable objects to ensure the smooth running of the program.

Detailed Finalize function

Finalize is a method that is located in the object class, and the access modifier for this method is protected, because all classes are subclasses of object, so the user class is easily accessible to this method. Because the Finalize function does not automatically implement chained calls, we must implement them manually, so the last statement of the Finalize function is usually super.finalize (). In this way, we can implement finalize calls from bottom to top, freeing our own resources before releasing the resources of the parent class.

According to the Java language Specification, the JVM guarantees that the object is unreachable until the Finalize function is called, but the JVM does not guarantee that the function will be called. In addition, the specification guarantees that the Finalize function runs at most once.

Many Java beginners will think that this method is similar to the destructor in C + +, the release of many objects, resources are placed in this function. In fact, this is not a very good way. There are three reasons why, in order for the GC to support the Finalize function, there is a lot of additional work to be done on the object that overrides the function. Second, after finalize runs, the object may become reachable, and the GC checks again if the object is reachable. Therefore, using finalize reduces the performance of the GC. Thirdly, because the time of the GC call to finalize is indeterminate, freeing the resource in this way is also indeterminate.

In general, finalize is used for the release of some non-manageable and very important resources, such as some I/O operations, data connections. The release of these resources is critical for the entire application. In this case, the programmer should be managed by the program itself, including the release of these resources, with the Finalize function to release resources as a supplement to form a double-insurance management mechanism, and should not rely solely on finalize to release resources.

An example is given below that the Finalize function may still be reachable after it is called, and that the finalize of an object can only run once.

1 class myobject{2  3 test main;//Record Test object in finalize for recovery of accessibility 4  5 public MyObject (Test t) 6  7 {8  9 main= T  Save test object}12 protected void Finalize () main.ref=this;//restore this object, so that this object can be up to ten System.out.println (\ "This is finalize\ ");//used to test finalize only run one time.}22,}24, class Test {MyObject ref;28, public static void main (String [] args) {test=new test (), Test.ref=new MyObject (test), Test.ref=null;//myobject object is unreachable, Finalize will be Use the System.GC (); if (test.ref!=null) System.out.println (\ "My object is still alive \"); 40 41}42 43}44 45 Operation Result: Inalize48 MyObject still alive.

In this example, it is important to note that although the MyObject object becomes reachable in finalize, finalize is no longer called when the next collection is made because the Finalize function is called only once.

How the program interacts with the GC

JAVA2 enhances the memory management feature by adding a JAVA.LANG.REF package that defines three reference classes. These three reference classes are SoftReference, WeakReference, and Phantomreference, respectively. By using these reference classes, programmers can interact with the GC to some extent to improve GC productivity. These reference classes have a reference strength between the unreachable object and the unreachable object.

It is also very easy to create a reference object, for example, if you need to create an soft reference object, first create an object and use a normal reference (up to the object), and then create a softreference to reference the object. Finally, the normal reference is set to null. In this way, the object has only one soft reference reference. At the same time, we call this object the soft Reference object.

The main feature of Soft reference is its strong reference function. This kind of memory is only recycled when there is not enough memory, so when memory is sufficient, they are usually not recycled. In addition, these reference objects guarantee that before Java throws a OutOfMemory exception, is set to NULL. It can be used to implement some common images of the cache, to achieve the function of the cache, to ensure maximum use of memory without causing outofmemory. The following shows the use of pseudo-code for this type of reference;

1//Apply an Image Object 2  3 image image=new image ();//Create Image Object 4  5 ... 6  7//Use image 8  9 ... 10 11//Use the image, set it to the soft reference type, and release the strong reference; SoftReference sr=new softreference (image), image=null;16 17 ... 18 19//Next use if (Sr!=null) Image=sr.get (); else{24 25//due to the fact that the GC has been released because of low memory, the image needs to be reloaded; Image=new image () 28 Sr=new softreference (image); 30 31}

The biggest difference between the weak reference object and the soft reference object is that the GC will need to check whether the soft reference object is reclaimed by the algorithm when it recycles, and the GC is always recycled for weak reference objects. Weak reference objects are more easily and faster to be recycled by GC. Although GC must recycle weak objects at run time, the weak object groups of complex relationships often require several GC runs to complete. Weak reference objects are often used in the map structure to refer to objects with a large amount of data, and once the strong reference to the object is NULL, the GC can quickly reclaim the object space.

Phantom references are less useful and are primarily used to assist in the use of finalize functions. The Phantom object refers to objects that have completed the Finalize function and are unreachable objects, but they have not yet been recycled by GC. This object can assist finalize with some later recycling, and we enhance the flexibility of the resource recovery mechanism by overriding the reference clear () method.

Some suggestions for Java coding

Based on how the GC works, we can make the GC run more efficiently and meet the requirements of the application in a number of tricks and ways. Here are a few suggestions for programming.

1. The most basic suggestion is to release the reference to the useless object as soon as possible. Most programmers use temporary variables to have the reference variable automatically set to null after exiting the active domain (scope). When we use this approach, we must pay special attention to complex object graphs, such as arrays, queues, trees, graphs, etc., which are more complex to refer to each other. For such objects, GC recycling is generally less efficient. If the program allows, the unused reference object will be assigned null as soon as possible. This will speed up the GC's work.

2. Use the Finalize function sparingly. The Finalize function is a chance that Java provides programmers with an opportunity to release objects or resources. However, it will increase the amount of GC work, and therefore minimize the use of a Finalize method to reclaim resources.

3. If you need to use a frequently used picture, you can use the Soft app type. It can save the picture in memory as much as possible for the program to call, without causing outofmemory.

4. Note the collection data types, including arrays, trees, graphs, linked lists and other data structures, which are more complex for GC to recycle. Also, be aware of some global variables, as well as some static variables. These variables tend to cause hanging objects (dangling reference), causing memory waste.

5. When the program has a certain wait time, the programmer can manually execute System.GC () to notify the GC to run, but the Java language specification does not guarantee that the GC will be executed. Using incremental GC can shorten the pause time for Java programs.

Category: Java Foundation =========================================================================================


    1. Java Garbage Collection Overview
    2. Java Memory Area
    3. How Java objects are accessed
    4. Java memory allocation mechanism
    5. Java GC Mechanism
    6. Garbage collector

Java Garbage Collection Overview

Java GC (Garbage Collection, garbage collection, garbage collector) mechanism, is one of the main differences between Java and C++/C, as a Java developer, generally do not need to specifically write memory recycling and garbage cleanup code, memory leaks and overflow problems, Nor does it need to be as jittery as C programmers. This is because there is an automatic memory management and garbage cleanup mechanism in the Java Virtual machine. In a nutshell, this mechanism marks the memory in the JVM (Java Virtual machine) and determines which memory needs to be recycled, automatically reclaims memory according to a certain recycling strategy, and never Stops (Nerver Stop) to ensure that the memory space in the JVM There is a memory leak and overflow problem with the placement.

With regard to the JVM, it is necessary to state that the JDK6, which is currently used by the largest sun company JDK, has been in widespread use since the JDK1.2 of 1999, where the default virtual machines are hotspots. Oracle acquired Sun in 2009 and the previously acquired EBA company, Oracle has two of the 3 largest virtual machines: JRockit and hotspot,oracle also demonstrate the intent to consolidate two virtual machines, but now in the newly released JDK7, The default virtual machine is still a hotspot, so the virtual machines introduced by default in this article are hotspots, and the mechanism is mainly referred to as the GC mechanism of the hotspot.

The Java GC mechanism mainly accomplishes 3 things: Determine what memory needs to be recycled, determine when to perform GC, and how to perform GC. After such a long period of development (in fact, before the advent of the Java language, there is the existence of GC mechanisms, such as Lisp language), the Java GC mechanism has been perfected, almost automatically for us to do most of the things. However, if we are engaged in large-size application software development, there have been memory optimization requirements, we must study the Java GC mechanism.

Learning the Java GC mechanism can help us troubleshoot various memory overflow or leak issues in our daily work, address performance bottlenecks, achieve higher concurrency, and write more efficient programs.

We will learn from 4 aspects of the Java GC mechanism, 1, how memory is allocated, 2, how to ensure that the memory is not garbage collected (that is, which memory needs to be recycled), 3, under what circumstances the GC and the way the GC is executed, 4, how to monitor and optimize the GC mechanism.

Java Memory Area

To understand the Java GC mechanism, you must first understand the partitioning of memory areas in the JVM. In the Java Runtime Data area, the memory area managed by the JVM is divided into several modules:


1, program Counter Register: The program counter is a small memory area that indicates that the current thread executes a byte code that executes to the first line, which can be understood as the line number indicator of the current thread. When the bytecode interpreter is working, it removes a statement instruction by changing the value of the counter.

Each program counter is used only to record the line number of a thread, so it is thread-private (a thread has a program counter).

If the program executes a Java method, the counter records the virtual machine bytecode instruction address that is executing, and if it is performing a local (native, written by C language) method, the value of the counter is undefined, since the program counter simply records the current instruction address, So there is no memory overflow, so the program counter is the only area in all JVM memory areas where OutOfMemoryError is not defined.

2, Virtual machine stack (JVM stack): Each method of a thread executes at the same time, will create a stack frame (statck frame), the stack frame stored in a local variable table, operation station, dynamic link, method exit, etc., when the method is called, stack frame in the JVM stack into the stack When the method execution completes, the stack frame is out of the stack.

The local variable table stores the relevant local variables of the method, including various basic data types, object references, return addresses, and so on. In a local variable table, only long and double types occupy 2 local variable spaces (slots, for 32-bit machines, one Slot is 32 bits), and the others are 1 slots. It is important to note that the local variable table is determined at compile time, and the space required for the method to run is fully deterministic in the stack frame and will not change during the lifetime of the method.

Two exceptions are defined in the virtual machine stack, which throws a statckoverflowerror (stack overflow) if the thread call has a stack depth greater than the maximum allowable depth for the virtual machine, but most Java virtual machines allow the size of the virtual machine stack to be dynamically extended (with a small number of fixed lengths). So the thread can always request the stack, knowing that there is not enough memory, at this point, will throw OutOfMemoryError (memory overflow).

Each thread corresponds to a virtual machine stack, so the virtual machine stack is also thread-private.

3, the local method stack (Native method Statck): The local methods stack in the role, the operation mechanism, the exception type and so on is the same as the virtual machine stack, the only difference is that the virtual machine stack is the Java method is executed, and the local method stack is used to execute the Native method, In many virtual machines, such as the Sun's JDK default hotspot virtual machine, the local method stack is used with the virtual machine stack.

The local method stack is also thread-private.

4, heap area (heap): Heap area is the most important area to understand the Java GC mechanism, not one. In memory managed by the JVM, the heap area is the largest chunk, and the heap area is the main memory area managed by the Java GC mechanism, which is shared by all threads and created when the virtual machine is started. The heap area exists to store object instances , in principle, all objects are allocated memory on the heap (although in modern technology, it is not so absolute, there are directly allocated on the stack).

In general, according to the Java Virtual Machine specification, heap memory needs to be logically continuous (not physically required), when implemented, can be fixed-size, or extensible, the current mainstream of virtual machines are extensible. If there is still not enough memory allocation and no expansion after the garbage collection is performed, the Outofmemoryerror:java heap space exception will be thrown.

There is much more to the heap area, which is described in detail in the next section, "Java memory allocation mechanism ".

5, Method area: In the Java Virtual Machine specification, the method area is treated as a logical part of the heap, but in fact, the method area is not a heap (non-heap); In addition, in many people's blogs, the Java GC's generational collection mechanism is divided into 3 generations: The green age, the old age, the permanent generation, these authors defined the method area as "permanent generation", because, for the previous implementation of the Hotspot Java Virtual machine, the idea of the collection of generations to extend to the method area, and the method area is designed to be a permanent generation. However, most virtual machines other than hotspot do not treat the method area as a permanent generation, and the hotspot itself also plans to cancel the permanent generation. In this article, because the author uses Oracle JDK6.0 primarily, the term permanent is still used.

A method area is a zone shared by each thread that stores the class information that has been loaded by the virtual machine (that is, information that needs to be loaded when the class is loaded, including information such as version, field, method, interface, and so on), final constants, static variables, code that the compiler compiles immediately, and so on.

The method area is not physically required to be contiguous, you can choose a fixed size or an extensible size, and the method area has one more limit than the heap: You can choose whether to perform garbage collection. Generally, garbage collection performed on the method area is rare, which is one of the reasons that the method area is known as a permanent generation (HotSpot), but this does not mean that there is no garbage collection on the method area at all, and that garbage collection on it is mainly for the memory reclamation of the constant pool and unloading of the loaded classes.

Garbage collection on the method area, the conditions are harsh and very difficult, the effect is not satisfactory, so generally do not do too much to consider, you can stay for further in-depth study later use.

The Outofmemoryerror:permgen space exception is defined on the method area and is thrown when there is insufficient memory.

The runtime Constant pool is a part of the method area that stores the literal constants, symbolic references, and direct references that are generated by the compilation period (the symbolic reference is that the encoding is the location of a variable, an interface by a string. The direct reference is the translated address according to the symbol reference, which will be translated in the class link phase); Run a constant pool in addition to storing compile-time constants, you can also store constants generated at runtime (such as The Intern () method of the String class, which acts as a constant pool maintained by string. If the character "ABC" that is called is already in the constant pool, the string address in the pool is returned, otherwise a new constant is added to the pool and the address is returned.

6, Direct memory: Direct memory is not the JVM management of memory, you can understand, direct memory, is the JVM outside the machine memory, for example, you have 4G of memory, the JVM occupies 1G, then the rest of 3G is the direct memory, In the JDK, there is a way to allocate memory based on channels (channel) and buffers (buffer), and the native libraries implemented by the C language are allocated in direct memory and referenced by the directbytebuffer stored in the JVM heap. OutOfMemoryError exceptions can also occur because direct memory is limited to the memory of this machine.

How Java objects are accessed

In general, a reference access to Java involves 3 memory areas: The JVM stack, the heap, the method area.

Refer to the simplest local variable: Object obj = new Object () for example:

    • Object obj represents a local reference, stored in the local variable table of the JVM stack, representing a reference type data;
    • The new object () is stored as instance object data in the heap;
    • The heap also records the address of type information (interface, method, field, object type, and so on) of the object class, and the data executed by these addresses is stored in the method area;

In the Java Virtual Machine specification, there are two main ways to implement a specific object by reference type reference:

1, accessed through a handle (figure from the in-depth understanding of Java Virtual machines: JVM advanced effects and best practices):

In the implementation of access through a handle, the JVM heap will have an area dedicated to the handle pool that stores the instance data addresses (including addresses in the heap and addresses in the method area) that are executed by the related handle. This implementation method is very stable because it represents the address with a handle.

2, accessed via direct pointer: (Figure from "in-depth understanding of Java Virtual machines: JVM advanced effects and best practices")

In the way of direct pointer access, reference stores the actual address of the object in the heap, and the object information stored in the heap contains the corresponding type data in the method area. The biggest advantage of this approach is that it is fast and is used in hotspot virtual machines.

Java memory allocation mechanism

The memory allocation mentioned here mainly refers to the allocation on the heap, the general, the memory allocation of the object is on the heap, but modern technology also supports splitting objects into scalar types (scalar types are atomic types, representing a single value, can be basic type or string, etc.), and then allocated on the stack, on the stack is seldom seen, We don't think about it here.

The mechanism of Java memory allocation and recycling is, in summary, the distribution of generational, generational recycling. The object will be divided according to the time of survival: young Generation, older generation (old Generation), permanent generation (Permanent Generation, which is the method area). if (from "become JAVAGC expert part I",


Young Generation: When objects are created, the allocation of memory occurs first in the younger generation (large objects can be created directly in the old age), and most of the objects are no longer used after they are created, and therefore quickly become unreachable, It was then cleaned up by the younger generation of GC mechanisms (IBM's research shows that 98% of objects are dying quickly), a GC mechanism called minor GC or young GC. Note that the Minor GC does not mean that the younger generation is out of memory, it actually represents only the GC on the Eden Zone.

The memory allocations for young generations are such that the young generation can be divided into 3 regions: Eden Area (Eden, where Adam and Eve ate the forbidden fruit doll, the area used to indicate the first allocation of memory) and two survival zones (Survivor 0, Survivor 1). The memory allocation process is (from "become JAVAGC expert part I",


    1. Most of the objects just created will be allocated to the Eden area, where most of the objects will soon perish. The Eden Zone is a contiguous memory space, so allocating memory on it is extremely fast;
    2. When the Eden area is full, the minor GC is executed, the extinct objects are cleared, and the remaining objects are copied to a surviving area Survivor0 (at this time, Survivor1 is blank, two survivor always have a blank);
    3. Thereafter, each time the Eden area is full, the minor GC is executed once, and the remaining objects are added to the Survivor0;
    4. When the Survivor0 is full, the objects that are still alive are copied directly to Survivor1, and after the Eden area executes the minor GC, the remaining objects are added Survivor1 (at this point, the Survivor0 is blank).
    5. Once the two survival zones have been switched several times (the Hotspot virtual machine defaults 15 times, with-xx:maxtenuringthreshold control, greater than this value entering the old age), the surviving objects (in fact only a small part, for example, our own defined objects) will be copied to the old age.

As can be seen from the above process, the Eden area is a contiguous space, and survivor always has a null. After a GC and copy, a survivor holds the currently alive object, while the contents of the Eden and the other survivor areas are no longer needed, and can be emptied directly to the next GC, with two survivor roles swapped. As a result, this way of allocating memory and cleaning up memory is extremely efficient, and this garbage collection is known as the "stop-copy (stop-and-copy)" Cleanup (copying the Eden area and an object that is still alive in a survivor to another survivor) , this does not mean that the stop copy cleanup method is very efficient, in fact, it is only in this case efficient, if used in the old age to stop copying, it is quite tragic.

In the Eden area, the hotspot virtual machine uses two techniques to speed up memory allocation. respectively, Bump-the-pointer and Tlab (thread-local Allocation buffers), the two techniques are: Because the Eden Zone is continuous, Therefore, the core of Bump-the-pointer technology is to track the last object created, when the object is created, only need to check if there is enough memory behind the last object, which greatly accelerates the memory allocation speed, and for Tlab technology is multi-threading, the Eden area is divided into several segment, each thread uses a separate paragraph to avoid mutual influence. Tlab combined with Bump-the-pointer technology will ensure that each thread uses a segment of the Eden Zone and allocates memory quickly.

old Generation: objects that survive long enough in a young generation without being cleaned up (that is, survived several times after the youth GC) are replicated to older generations, where older generations are generally larger than younger generations and can store more objects. The number of GCS that occur on older generations is also less than in younger generations. When the old generation is out of memory, the major GC will be executed, also called the full GC.

You can use the-xx:+useadaptivesizepolicy switch to control whether a dynamic control strategy is used, and dynamically adjust the size of each area in the Java heap and the age at which you enter the old age.

If the object is large (such as a long string or a large array), and young is not in space, then the large object will be allocated directly to the old age (large objects may trigger an advance GC, should be used sparingly, and should avoid the use of short-lived large objects). Use-xx:pretenuresizethreshold to control the size of objects directly ascending into older generations, and objects larger than this value are allocated directly to the old age.

There may be cases where older generations of objects refer to a new generation of objects, and if you need to perform a young GC, you may need to query the entire old age to determine whether you can clean up the collection, which is obviously inefficient. The solution is to maintain a block of byte-"card table" in the old generation, where all the records of older objects referencing the Cenozoic objects are recorded here. Young GC, as long as check here can, no longer to check all the old age, so performance greatly improved.

Java GC Mechanism

The basic algorithm of GC mechanism is: collection of generations, this need not repeat. The collection methods for each generation are described below.


Young generations:

In fact, in the previous section, we have introduced the new generation of major garbage collection methods, in the Cenozoic, using the "Stop-copy" algorithm to clean up, the new generation of memory divided into 2 parts, 1 parts of the Eden region larger, 1 parts survivor smaller, and is divided into two equal parts. Each time you clean up, copy the Eden area and an object that is still alive in the survivor to another survivor, and then clean up the Eden and the survivor just now.

It can also be found here that the two parts of the stop-copying algorithm are not always equal (the traditional stop-copy algorithm has two parts of memory equal, but the new generation uses 1 large Eden areas and 2 small survivor areas to avoid this problem)

Because most of the objects are short-lived, and even survived the survivor, so the Eden area and the survivor ratio is larger, the hotspot default is 8:1, that is, the 80%,10%,10% of the Cenozoic respectively. If the amount of memory survived in the Survivor+eden is more than 10% in a single collection, some of the objects need to be allocated to the old age. Use the-xx:survivorratio parameter to configure the capacity ratio of the Eden Zone Survivor area, which is 8 by default, representing Eden:survivor1:survivor2=8:1:1.

  Old Age:

The old age stores more objects than the younger generation, and there are large objects, in the old age of memory cleanup, if you use the stop-copy algorithm, it is quite inefficient.     In general, the algorithm used in the old age is the marker-collation algorithm, that is, mark out the surviving objects (which are referenced) and move all the surviving objects to one end to ensure the memory is contiguous. In the event of a minor GC, the virtual opportunity checks whether the size of each promotion into the old age is greater than the remaining space size of the old age, and if it is greater, it triggers the full GC directly, otherwise the-xx:+handlepromotionfailure is set (allowing the warranty to fail) , if allowed, only MINORGC is tolerated, memory allocation fails, and if not allowed, full GC is still performed (this means that if-xx:+handle promotionfailure is set, triggering MINORGC triggers the full GC at the same time. Even if there is a lot of memory in the old age, it is best not to do so.

  Method Area (permanent generation):

There are two types of recovery for a permanent generation: constant pool constants, useless class information, constant recycling is simple, no references can be recycled. For recycling of useless classes, 3 points must be guaranteed:

    1. All instances of the class have been recycled
    2. The ClassLoader of the loaded class has been recycled
    3. Class object is not referenced (that is, where the class is not referenced by reflection)
Recovery of a permanent generation is not required, and parameters can be used to set whether the class is recycled. Hotspot provides-XNOCLASSGC for control using-verbose,-xx:+traceclassloading,-xx:+traceclassunloading can view class load and unload information-verbose,-xx:+ Traceclassloading can be used in the product version of the hotspot,-xx:+traceclassunloading requires the Fastdebug version of Hotspot support

Garbage collector

In the GC mechanism, the important role is the garbage collector, garbage collector is the implementation of the GC, the Java Virtual Machine specification for the garbage collector does not have any provisions, so different vendors implement the garbage collector is not the same, the HotSpot 1.6 version of the garbage collector (figure from the " In-depth understanding of Java Virtual machines: JVM advanced effects and best practices, the two collectors in the diagram have lines between them, indicating that they can be used together:



Before introducing the garbage collector, it is important to be clear that in the new generation of stop-replication algorithms, the Meaning of "stop (Stop-the-world)" is to suspend execution of all other threads while reclaiming memory. This is inefficient, and now a variety of new generation collectors are optimizing this point, but still only the time to stop is shortened, not completely canceled stop.

    • serial Collector: The new generation collector, using the Stop replication algorithm, uses one thread for GC, and other worker threads to pause. Use-XX:+USESERIALGC to run memory reclamation using serial+serial old mode (this is also the default value that the virtual machine runs in client mode)
    • parnew Collector: The New generation collector, using the Stop copy algorithm, The multi-threaded version of the serial collector, with multiple threads for GC, other worker threads paused, focused on shortening the garbage collection time. Use the-XX:+USEPARNEWGC switch to control the collection of memory using the parnew+serial old collector combination, and use-xx:parallelgcthreads to set the number of threads that perform memory reclamation.
    • Parallel Scavenge collector: The new generation collector, using the Stop Replication algorithm, focuses on CPU throughput, that is, the time/total time to run user code, such as: The JVM runs for 100 minutes, which runs user code 99 minutes, garbage collection 1 minutes, The throughput is 99%, the collector can use the most efficient CPU, suitable for running background operations (attention to shorten the garbage collection time collector, such as CMS, waiting time is very small, so suitable for user interaction, improve the user experience). Use the-XX:+USEPARALLELGC switch to control the garbage collection using the Parallel scavenge+serial old collector (which is also the default value in server mode); Use-XX: Gctimeratio to set the proportion of user execution time to total time, default 99, which is 1% of the time used for garbage collection. Use-xx:maxgcpausemillis to set the maximum pause time for GC (this parameter is only valid for parallel scavenge)
    • Serial old collector: older collectors, single-threaded collectors, using tag grooming (cleanup) and compact (compact), clean-up is the discarded object, only the surviving objects, compression is moving the object, Fill the space to ensure that the memory is divided into 2 pieces, a whole object, a piece of idle) algorithm, using single-threaded GC, other worker thread paused (note, in the old age of the labeling algorithm cleanup, also need to suspend other threads), before JDK1.5, Serial The old collector is used in conjunction with the Parallelscavenge.
    • Parallel old collector: older collector, multi-threaded, multi-threaded mechanism with Parallel scavenge bad, using tag collation (unlike serial, here is the summary (summary) and compact (compression) , the summary means that the surviving objects are copied to the pre-prepared area, rather than the algorithm that cleans up the discarded objects like sweep (cleanup), and the other threads still need to be paused when parallel old executes. Parallel old is useful in multicore computing. Parallel Old appeared (JDK 1.6), with the Parallel scavenge with a good effect, fully embodies the Parallel scavenge collector throughput first effect. Use the-XX:+USEPARALLELOLDGC switch to control the collection using the Parallel scavenge +parallel old combo collector.
    • CMS (Concurrent Mark Sweep) Collector: The old collector, dedicated to obtaining the shortest recovery pause time, using the tag cleanup algorithm, multi-threading, the advantage is concurrent collection (the user thread can work concurrently with the GC thread), the pause is small. Use-XX:+USECONCMARKSWEEPGC for memory reclamation of parnew+cms+serial old, take precedence over PARNEW+CMS (see later), and when the user thread is out of memory, use the fallback scenario Serial old collection.
CMS collects the method is: first 3 times mark, then 1 clears, 3 times the first two marks in the mark is the initial mark and the re-mark (at this time still need to stop (stop the World)), the initial tag (Initial Remark) is the object that the GC roots can be associated with (that is, the object that has the reference) , the pause time is short, the concurrency token (Concurrent remark) is the process of performing a GC roots lookup reference, does not require a user thread to pause, and the re-tagging (remark) is the part of the marked change that needs to be marked during the initial and concurrent tags, so add this part The process of marking, the pause time is much smaller than the concurrent tag, but slightly longer than the initial tag. After the token is completed, the concurrency cleanup begins without requiring a user thread to pause. Therefore, in the CMS cleanup process, only the initial marking and re-tagging need a short pause, concurrent tagging and concurrent cleanup do not need to pause the user thread, it is highly efficient and suitable for high-interaction situations. The CMS also has drawbacks, it needs to consume additional CPU and memory resources, when CPU and memory resources are tight, CPU is less, it will increase the system burden (CMS default boot thread number is (CPU number +3)/4). In addition, in the concurrent collection process, the user thread is still running, still produce memory garbage, so it is possible to generate "floating garbage", this time can not be cleaned up, only the next full GC cleanup, so during the GC, you need to reserve enough memory for the user thread to use. So the collector using the CMS is not the old age to trigger full GC, but to use the more than half (default 68%, that is, 2/3, set with-xx:cmsinitiatingoccupancyfraction), it is necessary to carry out fully GC, If the user thread consumes memory that is not particularly large, you can properly raise the-xx:cmsinitiatingoccupancyfraction to reduce the number of GC times and improve performance, if the reserved user thread memory is not enough, it will trigger concurrent Mode Failure, At this point, the fallback scenario will be triggered: collect using the serial old collector, but the pause time is long, so the-xx:cmsinitiatingoccupancyfraction should not be too large. Also, the CMS uses a markup cleanup algorithm that causes memory fragmentation and can be used to set whether to defragment after the full GC,-xx:+usecmscompactatfullcollection Use-xx:cmsfullgcsbeforecompaction to set the full GC with compression once, after the number of uncompressed full GC executions.  
    • G1 Collector: Officially released in JDK1.7, with the current situation of the new generation, the concept of old age is very different, the current use less, do not introduce.
Note the difference between concurrency (Concurrent) and Parallelism (Parallel):       Concurrencymeans that the user thread executes concurrently with the GC thread (not necessarily parallel, possibly alternately, but in general) and does not need to pause the user thread (in fact, the user thread in the CMS still needs to be paused, only very short, and the GC thread executes on the other CPU);       ParallelCollection means that multiple GC threads work in parallel, but the user thread is paused at this point, so the serial and parallel collectors are parallel, and the CMS collector is concurrent. for JVM parameter configuration and memory tuning examples, see my next blog (in writing: Java series notes (4)-JVM monitoring and tuning), originally wanted to write in the same blog, but too much content, had to another. Description:This article is the 3rd chapter of the Java series of notes, this article wrote for a long time, mainly Java memory and GC mechanism is relatively complex, difficult to understand, plus I this period of time projects and life spent a lot of time, so slow progress.  Most of the notes in this article come from the blogs I found on the web and the "deep understanding of Java Virtual machines: JVM advanced effects and best practices." I have limited ability, if there are mistakes, please leave a message. References:Java programming thought, 5th Chapter, Java depth Adventure, Java garbage collection mechanism and reference type; deep understanding of Java Virtual machines: JVM advanced effects and best practices, 第2-3; Become a JAVAGC expert part ii-How to monitor the Java garbage collection mechanism, garbage Collection Optimization--don ' t pause, "original" Java Memory Area Understanding-preliminary understanding, good text to the top attention to my collection of the text of a PIN
Fans-3 + plus attention00? Previous post: Java Process Control
? Next: Modifiers in the Java language

How a good Java programmer must understand how the GC works

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.