How Do I Become a Trash Collector?
Java garbage collection, a JAVA-specific feature, garbage collection means that the objects that the program no longer needs are "useless information", and this information will be discarded and collected.
java garbage collection
Right!
- java
- In C ++, the memory occupied by an object is occupied until the program finishes running and cannot be allocated to other objects until it is explicitly released. In Java, when no object reference points to the memory originally allocated to an object, the memory It becomes garbage. A system-level thread of the JVM will automatically release the memory block. Garbage collection means that the objects that are no longer needed by the program are "useless information" that will be discarded. When an object is no longer referenced, memory reclaims the space it occupied so that the space can be used by later new objects. In fact, in addition to releasing useless objects, garbage collection can also clear memory record fragments. Fragmentation of memory occurs due to the object creation and the garbage collector freeing the memory space occupied by discarded objects. Fragmentation is a free memory hole between memory blocks allocated to an object. Defragmentation moves the occupied heap memory to one end of the heap, and the JVM allocates the sorted memory to new objects.
Garbage collection can automatically free up memory space, reducing the burden of programming. This gives the Java virtual machine some advantages. First, it can make programming more efficient. Without a garbage collection mechanism, it can take a lot of time to solve a difficult memory problem. When programming in the Java language, relying on the garbage collection mechanism can greatly reduce time. The second is that it protects the integrity of the program. Garbage collection is an important part of the Java language security strategy.
One potential disadvantage of garbage collection is that its overhead affects program performance. The Java virtual machine must track useful objects in the running program, and eventually release useless objects. This process requires processor time. Secondly, the incompleteness of the garbage collection algorithm, some of the garbage collection algorithms adopted earlier cannot guarantee that 100% of all waste memory is collected. Of course, with the continuous improvement of garbage collection algorithms and the continuous improvement of software and hardware operating efficiency, these problems can be solved.
Generally speaking, Java developers can ignore the allocation of heap memory and garbage collection in the JVM, but a full understanding of this feature of Java allows us to use resources more efficiently. At the same time, it should be noted that the finalize () method is Java's default mechanism. Sometimes to ensure the explicit release of object resources, you can write your own finalize method.
- The Java language specification does not explicitly specify which garbage collection algorithm the JVM uses, but any kind of garbage collection algorithm generally has to do 2 basic things: (1) find useless information objects; (2) recycle memory space occupied by useless objects So that the space can be used again by the program.
Most garbage collection algorithms use the concept of a root set; the so-called root set is the set of reference variables (including local variables, parameters, and class variables) that a running Java program can access. Programs can use reference variables to access objects Properties and methods of calling objects. The first choice for garbage collection is to determine which ones are reachable and which are unreachable from the root. The objects reachable from the root set are all active objects, and they cannot be collected as garbage. This also includes objects that are indirectly reachable from the root set. . Objects that are not reachable by the root set through any path are eligible for garbage collection and should be recycled. Here are some commonly used algorithms.
1.Reference Counting Collector
The reference counting method is the only method that does not use the garbage collection of the root set. This algorithm uses a reference counter to distinguish live objects from objects that are no longer used. In general, each object in the heap corresponds to a reference counter. Each time an object is created and assigned 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 goes out of scope (the object is discarded and no longer used), the reference counter is decremented by 1. Once the reference counter is 0, the object meets the garbage collection conditions .
The garbage collector based on the reference counter runs faster, does not interrupt program execution for a long time, and suitably programs that must run in real time. But the reference counter increases the overhead of program execution, because each time an object is assigned to a new variable, the counter is incremented by 1, and each time an existing object goes out of scope, the counter is decremented by 1.
2, tracing algorithm (Tracing Collector)
The tracing algorithm is proposed to solve the problem of reference counting, and it uses the concept of root set. The garbage collector based on the tracing algorithm scans from the root set to identify which objects are reachable and which are not reachable, and mark the reachable objects in some way, such as setting one or more bits for each reachable object. During the scan recognition process, garbage collection based on the tracing algorithm is also called a mark-and-sweep garbage collector.
3.Compacting algorithm
In order to solve the problem of heap fragmentation, the tracing-based garbage collection absorbs the idea of the Compacting algorithm. During the cleaning process, the algorithm moves all objects to one end of the heap, and the other end of the heap becomes an adjacent free memory area. The collector updates all references to all objects it moves so that those references can identify the original object in the new location. In the implementation of a collector based on the Compacting algorithm, a handle and a handle table are generally added.
4.Copying algorithm (Coping Collector)
The algorithm is proposed to overcome the overhead of handles and to solve the garbage collection of heap fragments. At the beginning, it divides the heap into an object plane and multiple free planes. The program allocates space for the object from the object plane. When the object is full, the garbage collection based on the coping algorithm scans the active objects from the root set and copies each active object. To the free surface (so that there is no free hole between the memory occupied by the active object), so that the free surface becomes the object surface, the original object surface becomes the free surface, and the program allocates memory in the new object surface.
A typical garbage collection based on the coping algorithm is the stop-and-copy algorithm, which divides the heap into an object plane and an idle region plane. During the process of switching between the object plane and the idle region plane, the program execution is suspended.
5, generation algorithm (Generational Collector)
One drawback of the stop-and-copy garbage collector is that the collector must copy all active objects, which increases the program wait time, which is why the coping algorithm is inefficient. There is a rule in program design: most objects exist for a short time, and few objects exist for a long time. Therefore, the generation algorithm divides the heap into two or more, with each sub-heap as the generation of the object. Since most objects exist for a short time, as the program discards unused objects, the garbage collector will collect these objects from the youngest subheap. After the generational garbage collector is run, the objects that survived the last run are moved to the sub-heap of the next highest generation. The sub-heap of the old generation is not often collected, which saves time.
6.adaptive algorithm (Adaptive Collector)
Under certain circumstances, some garbage collection algorithms will outperform others. A garbage collector based on the Adaptive algorithm is a garbage collector that monitors the current heap usage and will select the appropriate algorithm.
- 1, command line parameters perspective garbage collector running System.gc () can be used regardless of which JVM uses the garbage collection algorithm, you can request Java garbage collection. There is a parameter -verbosegc on the command line to view the heap memory used by Java. Its format is as follows:
java -verbosegc classfile
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, the object becomes quickly reachable. After the program is compiled, execute the command: java -verbosegc TestGC The result is:
[Full GC 168K-> 97K (1984K), 0.0253873SECS]
The environment of the machine is Windows 2000 + JDK1.3.1. The data before and after the arrow 168K and 97K respectively indicate the memory capacity used by all surviving objects before and after garbage collection GC, indicating that the object capacity of 168K-97K = 71K was recovered. 1984K is the total capacity of the heap memory. The time required for collection is 0.0253873 seconds (this time will be different at each execution).
2, finalize method perspective garbage collector operation Before the JVM garbage collector collects an object, the program is generally required to call the appropriate method to release resources, but in the absence of explicit release of resources, Java provides a default mechanism to terminate The object center releases resources. This method is finalize (). Its prototype is:
protected void finalize () throws Throwable
After the finalize () method returns, the object disappears and garbage collection begins. The throws Throwable in the prototype indicates that it can throw any type of exception.
The reason to use finalize () is because sometimes it is necessary to take a different method from Java's ordinary method and do some C-style things by allocating memory. This can be done mainly through "inherent methods", which is a way to call non-Java methods from Java. C and C ++ are the only languages currently supported by native methods. But because they can call subprograms written in other languages, they can call anything effectively. Inside non-Java code, you may be able to call C's malloc () series of functions and use it to allocate storage space. And unless free () is called, the storage space will not be released, which will cause a memory "hole". Of course, free () is a C and C ++ function, so we need to call it in an intrinsic method inside finalize (). In other words, we can't use finalize () too much, it is not an ideal place for general cleanup.
In normal cleanup, in order to clear an object, the user of that object must call a cleanup method at the place where the cleanup is desired. This contradicts the concept of the C ++ "breaker". In C ++, all objects are destroyed (cleaned). Or in other words, all objects "should" be destroyed. If you create a C ++ object as a local object, such as on the stack (which is not possible in Java), then the cleanup or destruction work will be at the end of the scope of the object represented by "end curly braces" get on. If the object is created with new (similar to Java), when the programmer calls the C ++ delete command (Java does not have this command), the corresponding destroyer will be called. If the programmer forgets, then the destroyer will never be called, and we will end up with a memory "hole", and other parts of the object will never be cleared.
In contrast, Java does not allow us to create local (local) objects-using new anyway. But in Java, there is no "delete" command to release objects, because the garbage collector will help us free up storage space automatically. So if we take a more simplified stand, we can say that it is because of the garbage collection mechanism that Java does not have a destroyer. However, as you learn more in the future, you will know that the existence of the garbage collector cannot completely eliminate the need for a destroyer, or that it cannot eliminate the need for the mechanism represented by the destroyer (and you must never call finalize () directly. , So try to avoid using it). If you want to perform some other form of clearing work other than freeing storage space, you must still call a method in Java. It is equivalent to the C ++ destroyer, but it is not as convenient as the latter.
The following example shows everyone 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 after" + 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 space");
}
System.out.println ("After all Chairs have been created: \ n" + "total created =" + Chair.created +
", Total finalized =" + Chair.finalized);
if (args.equals ("before")) {
System.out.println ("gc ():");
System.gc ();
System.out.println ("runFinalization ():");
System.runFinalization ();
}
System.out.println ("bye!");
if (args.equals ("after"))
System.runFinalizersOnExit (true);
}
}
The above program creates many Chair objects, and at some point after the garbage collector starts running, the program stops creating Chairs. Since the garbage collector may run at any time, we cannot know exactly when it will start. Therefore, the program uses a flag called gcrun to indicate whether the garbage collector has started running. With the second flag f, Chair can tell main () that it should stop generating objects. Both of these flags are set inside finalize (), which is called during garbage collection. The other two static variables-created and finalized-are used to track the number of objects that have been created and the number of objects that the garbage collector has completed. Finally, each Chair has its own (non-static) int i, so you can track what its specific number is. After the finishing work of Chair No. 47 is finished, the flag will be set to true, and finally the creation process of the Chair object is ended.
- After the above description, we can find the following characteristics of garbage collection:
(1) Unpredictability of garbage collection: Because different garbage collection algorithms are implemented and different collection mechanisms are used, it may happen periodically, it may happen when the system has free CPU resources, or it may be As with the original garbage collection, it happens when the memory consumption reaches its limit, which is related to the choice of the garbage collector and the specific settings.
(2) Accuracy of garbage collection: mainly includes 2 aspects: (a) the garbage collector can accurately mark the living objects; (b) the garbage collector can accurately locate the reference relationship between the objects. The former is a prerequisite for completely recycling all discarded objects, otherwise it may cause memory leaks. The latter is a necessary condition for implementing algorithms such as merge and copy. All unreachable objects can be reliably collected, and all objects can be re-allocated, allowing object replication and object memory shrinkage, which effectively prevents memory fragmentation.
(3) There are now many different garbage collectors, each with its own algorithm and different performance, both stopping the application when the garbage collection starts, and allowing the application when the garbage collection starts Threads run, and there are multiple threads running for garbage collection at the same time.
(4) The implementation of garbage collection is closely related to the specific JVM and the memory model of the JVM. Different JVMs may use different garbage collections, and the memory model of the JVM determines which types of garbage collection the JVM can use. Now, the memory systems in the HotSpot series of JVMs all adopt advanced object-oriented framework design, which makes this series of JVMs adopt the most advanced garbage collection.
(5) With the development of technology, modern garbage collection technology provides many optional garbage collectors, and different parameters can be set when configuring each collector, which makes it possible to obtain the optimal one according to different application environments. Application performance becomes possible.
- (1) Don't try to assume the time when garbage collection occurs, all this is unknown. For example, a temporary object in a method becomes a useless object after the method is called, and its memory can be released at this time.
(2) Java provides some classes that deal with garbage collection, and also provides a way to force garbage collection-call System.gc (), but this is also an uncertain method. Java does not guarantee that garbage collection can be started every time this method is called. It just sends such an application to the JVM. Whether or not garbage collection is actually performed is unknown.
(3) Pick a garbage collector that suits you. In general, if the system does not have special and demanding performance requirements, you can use the JVM default options. Otherwise, you can consider using a targeted garbage collector, such as the incremental collector, which is more suitable for systems with high real-time requirements. The system has a higher configuration and has more idle resources. You can consider using a parallel mark / clear collector.
(4) The key and difficult to grasp is the memory leak. Good programming habits and rigorous programming attitude are always the most important. Don't let a small mistake of yourself lead to a large leak in memory.
(5) Release references to useless objects as soon as possible. When most programmers use temporary variables, the reference variable is automatically set to null after exiting the active scope. This implies that the garbage collector should collect the object. It must also pay attention to whether the referenced object is monitored. If so, remove the listener and assign a null value.