The working principle of the JAVA garbage collection mechanism __java

Source: Internet
Author: User
Tags garbage collection throwable
The working principle of the Java garbage collection mechanism.

Java's heap is a run-time data area in which instances (objects) of the class allocate space. The Java Virtual machine (JVM) heap stores all objects that are established by the running application, which are established through directives such as new, NewArray, Anewarray, and Multianewarray, but they do not require program code to be released explicitly. In general, the heap is responsible for garbage collection, although the JVM specification does not require special garbage collection techniques or even garbage collection at all, but because of the limited memory, the JVM has a heap managed by garbage collection at the time of implementation. Garbage collection is a dynamic storage management technology, which automatically frees objects that are no longer referenced by programs, and implements the function of automatic resource recovery according to specific garbage collection algorithms.

The significance of garbage collection

In C + +, the memory of an object is occupied until the program is finished running, and cannot be allocated to other objects until it is explicitly released, whereas in Java the memory becomes garbage when no object reference points to the memory originally allocated to an object. A system-level thread in the JVM automatically frees the memory block. Garbage collection means that the object that the program no longer needs is "useless information", and the information is discarded. When an object is no longer referenced, the memory reclaims the space it occupies so that the space is used by the new object later. In fact, garbage collection can erase memory fragments in addition to releasing useless objects. Memory fragmentation occurs because the object is created and the garbage collector frees up the memory space of the discarded object. Fragmentation is a free memory hole between the memory blocks assigned to an object. Defragmentation moves the heap memory occupied to one end of the heap, and the JVM assigns the sorted memory to the new object.

Garbage collection automatically frees up memory space and reduces the burden of programming. This makes Java virtual machines have some advantages. First, it can make programming more efficient. In the absence of a garbage collection mechanism, it may take a lot of time to solve a difficult memory problem. When programming in the Java language, the garbage collection mechanism can greatly shorten the time. The second is that it protects the integrity of the program, and garbage collection is an important part of the Java language security policy.

A potential drawback to garbage collection is that its overhead affects program performance. The Java virtual machine must track the objects that are useful in running programs and eventually release the useless objects. This process takes a processor's time. Second, the incompleteness of the garbage collection algorithm, some of the previous garbage collection algorithms can not guarantee that 100% of all the discarded memory. Of course, with the continuous improvement of garbage collection algorithm and the increasing efficiency of software and hardware, these problems can be solved.

Algorithm analysis of garbage collection

The Java language Specification does not explicitly describe which garbage collection algorithm the JVM uses, but any garbage collection algorithm typically does 2 basic things: (1) Discovering unwanted information objects, and (2) reclaiming the memory space occupied by unwanted objects so that the space can be reused by the program.

Most garbage collection algorithms use the concept of root set (root set), which refers to the collection of reference variables (including local variables, parameters, class variables) that can be accessed by the Java program in which the program is executing, and can use reference variables to access the object's properties and invoke the object's methods. The garbage collection preference needs to determine what is accessible from the root and what is not, and the objects from the root set are active objects that cannot be reclaimed as garbage, which also includes objects that are indirectly accessible from the root set. The root set, which can not be reached through any path, is eligible for garbage collection and should be recycled. Here are a few common algorithms.

1, reference counting method (Reference counting Collector)

Reference counting is the only method that does not use the root set for garbage collection, which uses reference counters to differentiate between surviving objects and objects that are no longer in use. In general, each object in the heap corresponds to a reference counter. When you create an object each time and assign it to a variable, the reference counter is set to 1. When an object is assigned to any variable, the reference counter is incremented by 1 each time the object is out of scope (discarded by the object), the reference counter is reduced by 1, and once the reference counter is 0, the object satisfies the garbage collection condition.

The garbage collector based on reference counters runs faster and does not interrupt program execution for a long time, and it is appropriate to run the program in real time. However, the reference counter increases the overhead of program execution because each object assigns a new variable to the counter plus 1, and each time an existing object is scoped, the counter is reduced by 1.

2, tracing algorithm (tracing Collector)

The tracing algorithm is proposed to solve the problem of reference counting method, which uses the concept of root set. The garbage collector based on the tracing algorithm begins scanning from the root set, identifying which objects can be reached, which objects are unreachable, and marking the accessible objects in some way, such as setting one or more bits for each accessible object. In the scanning identification process, garbage collection based on the tracing algorithm is also known as the tag and Purge (Mark-and-sweep) garbage collector.

3, compacting algorithm (compacting Collector)

To solve the heap fragmentation problem, garbage collection based on tracing absorbs the idea of the compacting algorithm, in which the algorithm moves all objects to one end of the heap, the other end of the heap becomes an adjacent free memory area, and the collector updates all references to all the objects it moves. So that these references can identify the original object in a new location. In the implementation of the collector based on the compacting algorithm, the handle and the handle table are generally added.

4, copying algorithm (coping Collector)

The proposed algorithm is designed to overcome the cost of the handle and to solve the garbage collection of heap fragments. It begins by dividing the heap into an object surface and multiple idle surfaces, the program allocates space for objects from the object surface, and when the object is full, garbage collection based on the coping algorithm scans the active object from the root set and copies each active object to the idle surface (so that there is no free hole between the active object's memory), The idle surface becomes the object surface, the original object surface becomes the idle surface, the program allocates memory in the new object face.

A typical garbage collection based on coping algorithm is stop-and-copy algorithm, which divides the heap into object plane and free area surface, and the program suspends execution in the process of switching between object surface and free area surface.

5, Generation algorithm (generational Collector)

One drawback of the stop-and-copy garbage collector is that the collector must replicate all active objects, which increases the latency of the program, which is why the coping algorithm is inefficient. In the program design, there is such a law: most objects exist in a relatively short time, a few of the existence of a long time. Therefore, the generation algorithm divides the heap into two or more, each of which is a generation of objects (generation). Because most objects exist for a relatively short time, the garbage collector collects the objects from the youngest child heap as the program discards unused objects. After the generational garbage collector runs, the last surviving object moves to the next highest-generation child heap, saving time because the older generation's child heap is not often recycled.

6, Adaptive Algorithm (adaptive Collector)

In certain cases, some garbage collection algorithms are superior to other algorithms. The garbage collector based on the adaptive algorithm monitors the current heap usage and will select the appropriate algorithm for the garbage collector.

Perspective Java Garbage Collection

1, command line parameters perspective garbage collector's Operation

2. Using System.GC () can request Java garbage collection regardless of which garbage collection algorithm is used by the JVM. There is a parameter on the command line-VERBOSEGC can view the heap memory used by Java, which is formatted as follows:

JAVA-VERBOSEGC Classfile

You can see an example:

Class TESTGC

{

public static void Main (string[] args)

{

New TESTGC ();

System.GC ();

System.runfinalization ();

}

}

In this example, a new object is created, because it is not used, so the object quickly becomes accessible, after the program compiles, executes the command: JAVA-VERBOSEGC TESTGC The result is:

[Full GC 168k->97k (1984K), 0.0253873 secs]

The environment of the machine is, Windows JDK1.3.1 +, the data 168K and 97K before and after the GC respectively indicate the amount of memory used by all the surviving objects before and after the garbage collection, indicating that the 168k-97k=71k object capacity is recycled, The 1984K of data in parentheses is the total capacity of the heap memory, and the time required for collection is 0.0253873 seconds (this time varies at each execution).

Before the JVM garbage collector collects an object, it is generally required that the program call the appropriate method to free the resource, but in the absence of a clear release of resources, Java provides a default mechanism to terminate the object's heart-releasing resources, which is finalize (). Its prototype is:

protected void Finalize () throws Throwable

After the Finalize () method returns, the object disappears and the garbage collection starts executing. The throws Throwable in the prototype indicates that it can throw any type of exception.

The reason to use Finalize () is that it is sometimes necessary to take a different approach than the common Java method of allocating memory to do something C-style. This can be done primarily through the "intrinsic approach", which is a way to invoke non-Java methods from Java. C and C + + are the only languages currently supported by intrinsic methods. But because they can invoke subroutines written in other languages, they can invoke anything effectively. Within non-Java code, you might be able to call the malloc () series function of C and use it to allocate storage space. and unless free () is invoked, storage space is not released, causing memory "vulnerabilities" to occur. Of course, free () is a C and C + + function, so we need to call it in an intrinsic method within Finalize (). That means we can't use Finalize () too much, and it's not the ideal place to do ordinary cleanup work.

In normal cleanup, to clear an object, the user of that object must invoke a purge method at the location where the cleanup is desired. This is slightly inconsistent with the concept of C + + "sabotage". In C + +, all objects are corrupted (cleared). Or in other words, all objects are "supposed" to be corrupted. If you create a C + + object as a local object, such as in the stack (which is not possible in Java), the cleanup or destruction work is done at the end of the scope that the end curly braces represents to create the object. If the object is created with new (similar to Java), then when the programmer invokes the C + + DELETE command (Java does not have this command), the corresponding device is invoked. If the programmer forgets, then never invokes the wreck, we end up with a memory "vulnerability" and another part of the object will never be erased.

Instead, Java does not allow us to create local (local) objects--using new anyway. In Java, however, there is no "delete" command to release objects, because the garbage collector helps us to automatically free up storage space. So if you stand in a simpler position, we can say that it is due to the existence of garbage collection mechanism, so Java does not have a broken device. However, as you learn later, you will know that the existence of the garbage collector does not completely eliminate the need for the destruction, or the need to eliminate the mechanism represented by the device (and absolutely cannot call finalize (), so try to avoid it). If you want to perform some sort of cleanup work other than freeing storage, you must still call a method in Java. It is equivalent to the C + + of the destruction, but not the latter convenient.

The following example shows you the process of garbage collection and summarizes the previous statements.

Class Chair {

static Boolean gcrun = false;

static Boolean f = false;

static int created = 0;

static int finalized = 0;

int i;

Chair () {

i = ++created;

if (created = 47)

System.out.println ("Created 47");

}

protected void Finalize () {

if (!gcrun) {

Gcrun = true;

System.out.println ("Beginning to finalize" + created + "chairs have been created");

}

if (i = = 47) {

System.out.println ("Finalizing Chair #47," + "Setting flag to stop Chair creation");

F = true;

}

finalized++;

If (finalized >= created)

System.out.println ("All" + finalized + "finalized");

}

}

public class Garbage {

public static void Main (string[] args) {

if (Args.length = = 0) {

System.err.println ("Usage: \ n" + "java garbage before\n or:\n" + "java Garbage after");

Return

}

while (! CHAIR.F) {

New Chair ();

New String ("to take up Spaces");

}

System.out.println ("After all chairs have been created:\n" + "total created =" + chair.created +

", Total finalized =" + chair.finalized);

if (Args[0].equals ("before")) {

SYSTEM.OUT.PRINTLN ("GC ():");

System.GC ();

System.out.println ("Runfinalization ():");

System.runfinalization ();

}

System.out.println ("bye!");

if (Args[0].equals ("after"))

System.runfinalizersonexit (TRUE);

}

}

2, tracing algorithm (tracing Collector)

The tracing algorithm is proposed to solve the problem of reference counting method, which uses the concept of root set. The garbage collector based on the tracing algorithm begins scanning from the root set, identifying which objects can be reached, which objects are unreachable, and marking the accessible objects in some way, such as setting one or more bits for each accessible object. In the scanning identification process, garbage collection based on the tracing algorithm is also known as the tag and Purge (Mark-and-sweep) garbage collector.

3, compacting algorithm (compacting Collector)

To solve the heap fragmentation problem, garbage collection based on tracing absorbs the idea of the compacting algorithm, in which the algorithm moves all objects to one end of the heap, the other end of the heap becomes an adjacent free memory area, and the collector updates all references to all the objects it moves. So that these references can identify the original object in a new location. In the implementation of the collector based on the compacting algorithm, the handle and the handle table are generally added.

4, copying algorithm (coping Collector)

The proposed algorithm is designed to overcome the cost of the handle and to solve the garbage collection of heap fragments. It begins by dividing the heap into an object surface and multiple idle surfaces, the program allocates space for objects from the object surface, and when the object is full, garbage collection based on the coping algorithm scans the active object from the root set and copies each active object to the idle surface (so that there is no free hole between the active object's memory), The idle surface becomes the object surface, the original object surface becomes the idle surface, the program allocates memory in the new object face.

A typical garbage collection based on coping algorithm is stop-and-copy algorithm, which divides the heap into object plane and free area surface, and the program suspends execution in the process of switching between object surface and free area surface.

5, Generation algorithm (generational Collector)

One drawback of the stop-and-copy garbage collector is that the collector must replicate all active objects, which increases the latency of the program, which is why the coping algorithm is inefficient. In the program design, there is such a law: most objects exist in a relatively short time, a few of the existence of a long time. Therefore, the generation algorithm divides the heap into two or more, each of which is a generation of objects (generation). Because most objects exist for a relatively short time, the garbage collector collects the objects from the youngest child heap as the program discards unused objects. After the generational garbage collector runs, the last surviving object moves to the next highest-generation child heap, saving time because the older generation's child heap is not often recycled.

6, Adaptive Algorithm (adaptive Collector)

In certain cases, some garbage collection algorithms are superior to other algorithms. The garbage collector based on the adaptive algorithm monitors the current heap usage and will select the appropriate algorithm for the garbage collector.

The above program creates many chair objects, and at some point after the garbage collector starts running, the program stops creating chair. Because the garbage collector may run at any time, we cannot know exactly when it will start. Therefore, the program uses a tag named Gcrun to indicate whether the garbage collector has started running. Using the second tag F,chair can tell main () that it should stop the object's generation. Both of these tags are set within finalize () and are used during garbage collection. The other two static variable--created and finalized--are used to track the number of objects created and the number of objects the garbage collector has finished finishing. Finally, each chair has its own (non-static) int I, so it can track what its specific number is. Chair with number 47 finishes the finishing work, the tag is set to true, and the Chair object is eventually created.

A few additions to garbage collection

After the above explanation, we can find that garbage collection has the following characteristics:

(1) The unpredictability of garbage collection occurs: Because different garbage collection algorithms are implemented and different collection mechanisms are in place, it can occur periodically, possibly when the system is idle CPU resources, and possibly the same as the original garbage collection, which occurs when memory consumption limits. This is related to the choice of the garbage collector and the specific settings.

(2) The accuracy of garbage collection: mainly includes 2 aspects: (a) The garbage collector can accurately mark the living object; (b) The garbage collector can pinpoint the referential relationship between objects. The former is a prerequisite for completely reclaiming all discarded objects, or it may cause a memory leak. The latter is the necessary condition to realize merging and copying algorithms. All unreachable objects can be reliably recycled, all objects can be reassigned, allowing object replication and object memory to shrink, effectively preventing memory fragmentation.

(3) There are many different kinds of garbage collectors, each with its own algorithm and performance, both when the garbage collection starts to stop the application running, and when the garbage collection starts to allow the application's thread to run, and at the same time garbage collection multithreading run.

(4) The implementation of garbage collection is closely related to the specific JVM and the memory model of the JVM. Different JVMs may take different garbage collections, and the JVM's memory model determines which types of garbage collection the JVM can take. The memory systems in the HotSpot series JVM are now designed with an advanced object-oriented framework that enables the most advanced collection of garbage collections in this series of JVMs.

(5) With the development of technology, modern garbage collection technology provides many optional garbage collectors, and can set different parameters when configuring each collector, which makes it possible to obtain the optimal applicability according to different application environments.

In view of the above characteristics, we should pay attention to when using:

(1) Do not attempt to assume that garbage collection occurs at the time, all of which are unknown. For example, a temporary object in a method becomes a useless object after the method call completes, and its memory can be freed.

(2) Java provides some classes that deal with garbage collection and provides a way to enforce garbage collection-call System.GC (), but this is also an indeterminate method. Java does not guarantee that the method will be able to start garbage collection every time it is invoked, it simply sends an application to the JVM, whether it really performs garbage collection, and everything is unknown.

(3) Select the appropriate garbage collector. In general, if your system does not have special and demanding performance requirements, you can use the JVM's default options. Otherwise, you might consider using targeted garbage collectors, such as incremental collectors, that are better suited to systems with higher real-time requirements. The system has a high configuration, there are more idle resources, you can consider using parallel tag/purge collector.

(4) The key is also difficult to grasp the problem is a memory leak. Good programming habits and rigorous programming attitude is always the most important, do not let your own a small error caused memory large holes.

(5) Release the reference of the unwanted object as soon as possible. Most programmers use a temporary variable, is to have the reference variable automatically set to null after exiting the active field (scope), implying that the garbage collector collects the object, and that the referenced object is listening, and if so, remove the listener and then assign a null value.

Conclusion

In general, Java developers can focus on the allocation of heap memory and garbage collection in the JVM, but a full understanding of this feature of Java allows us to make more efficient use of resources. Also note that the Finalize () method is the default mechanism for Java, and sometimes you can write your own Finalize method to ensure explicit release of object resources.

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: info-contact@alibabacloud.com 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.