Directory
- Java Garbage Collection Overview
- Java Memory Area
- How Java objects are accessed
- Java memory allocation mechanism
- Java GC Mechanism
- 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:
which
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", http://www.importnew.com/1993.html):
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", http://www.importnew.com/1993.html):
- 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;
- 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);
- Thereafter, each time the Eden area is full, the minor GC is executed once, and the remaining objects are added to the Survivor0;
- 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).
- 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:
- All instances of the class have been recycled
- The ClassLoader of the loaded class has been recycled
- 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, http://www.importnew.com/2057.htmlJDK5.0 garbage Collection Optimization--don ' t pause,http://calvin.iteye.com/blog/91905 "original" Java Memory Area Understanding-preliminary understanding, http://iamzhongyong.iteye.com/blog/1333100
Java memory Zoning and GC mechanisms