In depth explanation of Java garbage collection

1. The core idea of garbage collection algorithm java language establishes a garbage collection mechanism to track objects in use and find and recycle objects that are no longer used (referenced). This mechanism can effectively prevent two possible dangers in dynamic memory allocation: memory depletion caused by excessive memory garbage and illegal memory reference caused by improper memory release.

The core idea of the garbage collection algorithm is to identify the available memory space of the virtual machine, that is, the object in the heap space. If the object is being referenced, it is called a living object. On the contrary, if the object is no longer referenced, it is a garbage object, and the space occupied by it can be recycled for redistribution. The selection of garbage collection algorithm and the reasonable adjustment of garbage collection system parameters directly affect the system performance, so developers need to have a more in-depth understanding.

2. The condition that triggers the primary GC (garbage collector) causes the JVM to perform secondary GC very frequently, but because this GC takes up a very short time, it has little impact on the system. More noteworthy is the trigger condition of the main GC, because it has an obvious impact on the system. In general, there are two conditions that trigger the main GC:

(1) GC is called when an application is idle, that is, when no application thread is running. Because GC is performed in the thread with the lowest priority, when the application is busy, the GC thread will not be called, except for the following conditions.

(2) GC is called when the Java heap is low on memory. When the application thread is running and creates a new object during the running process, if the memory space is insufficient, the JVM will forcibly call the GC thread to reclaim memory for new allocation. If the memory allocation requirements are still not met after one GC, the JVM will make two more GC attempts. If the requirements are still not met, the JVM will report an error of "out of memory" and the Java application will stop.

Since whether to perform the main GC is determined by the JVM according to the system environment, and the system environment is constantly changing, the operation of the main GC is uncertain, and it is impossible to predict when it will inevitably occur, but it can be determined that for a long-running application, the main GC is repeated.

3. Measures to reduce GC overhead according to the above GC mechanism, the operation of the program will directly affect the change of the system environment, thus affecting the triggering of GC. If we do not design and code according to the characteristics of GC, a series of negative effects such as memory persistence will occur. In order to avoid these effects, the basic principle is to reduce garbage and reduce the overhead in the GC process as much as possible. Specific measures include the following aspects:

(1) Do not explicitly call system Gc() this function suggests the JVM to perform the main GC. Although it is only a suggestion rather than a certain one, it will trigger the main GC in many cases, thus increasing the frequency of the main GC, that is, increasing the number of intermittent pauses. In particular, it should be noted that the call system. Net shown in the code GC () may not be able to perform GC. We can verify this through the finalize () method, that is, actively call system GC () does not necessarily call the finalize () method every time. The characteristic of the finalize () method is to call the finalize () method before the object is recycled.

(2) Minimize the use of temporary objects. Temporary objects will become garbage after jumping out of function calls. Less use of temporary variables is equivalent to reducing the generation of garbage, thus prolonging the occurrence time of the above second trigger condition and reducing the opportunity of main GC.

(3) When an object is not used, it is best to explicitly set it to null. Generally speaking, null objects will be treated as garbage. Therefore, explicitly setting unused objects to null is conducive to the GC collector to determine garbage, thus improving the efficiency of GC.

(4) Try to use StringBuffer instead of string to accumulate strings (see string and StringBuffer in Java in another blog article for details). Since string is a fixed length string object, when accumulating string objects, you do not expand them in one string object, but recreate new string objects, such as str5 = STR1 + STR2 + str3 + str4. Multiple garbage objects will be generated during the execution of this statement, Because new string objects must be created for the next "+" operation, but these transition objects have no practical significance to the system and will only add more garbage. To avoid this situation, you can use StringBuffer to accumulate strings. Because StringBuffer is variable length, it expands on the original basis and will not produce intermediate objects.

(5) If you can use basic types such as int and long, you don't need integer. The memory resources occupied by long object basic type variables are much less than those occupied by corresponding objects. If it's not necessary, you'd better use basic variables. When do I need to use integer?

(6) Minimize the use of static object variables. Static variables belong to global variables and will not be recycled by GC. They will always occupy memory.

(7) Scattered object creation or deletion time is concentrated on creating a large number of new objects in a short time, especially large objects, which will lead to a sudden need for a large amount of memory. When facing this situation, the JVM can only perform the main GC to recover memory or integrate memory fragments, so as to increase the frequency of the main GC. The same is true for centralized deletion of objects. It makes a large number of garbage objects appear suddenly, and the free space must be reduced, which greatly increases the opportunity to force the main GC when creating a new object next time.

4. Garbage collection algorithm (1) reference counting collector reference counting is an early strategy of garbage collection. In this method, each object in the heap has a reference count. When an object is created and a reference to the object is assigned to a variable, the reference count of the object is set to 1. For example, create a new object a = new a(); Then a is assigned to another variable B, that is, B = a; Then the reference count of object a is + 1. When any other variable is assigned a reference to this object, the count is incremented by 1. When the reference of an object exceeds its lifetime or a new value is set, the reference count of the object is reduced by 1. For example, if B = C, the reference count of a is - 1. Any object with a reference count of 0 can be garbage collected. When an object is garbage collected, the count of any objects it references is reduced by 1. In this method, after an object is garbage collected, it may lead to subsequent garbage collection actions of other objects. For example, a = new a(); b=a; When B is garbage collected, the reference count of a becomes 0, which causes a to be garbage collected as well.

Method: the reference count collector can be executed quickly and interleaved in the operation of the program. This reminder is good for a real-time environment where the program cannot be interrupted for a long time.

The disadvantage of the method: the reference count cannot detect a loop (that is, two or more objects refer to each other). For example, the parent object has a reference to the child object, and the child object references the parent object in turn. In this way, the object user can't count to 0, even if they can't be touched by the root object of the executing program. Another disadvantage is that each increase or decrease of the reference count brings additional overhead.

(2) Trace collector garbage detection is usually achieved by establishing a collection of root objects and checking accessibility from these root objects. If there is a reference path between the root object that the executing program can access and an object, the object is reachable. For programs, the root object is always accessible. Starting from these root objects, any object that can be touched is considered an "active" object. Objects that cannot be touched are considered garbage because they no longer affect the future execution of the program.

A trace collector is an object reference graph that traces objects from the root node. Objects encountered during tracking are marked with a hand. In general, you can either set the tag on the object itself or set the tag with a separate bitmap. At the end of tracking, unmarked objects are inaccessible and can be collected.

The basic tracking algorithm is called "mark and clear". The name points out two stages of junk mobile phones. In the marking phase, the garbage collector traverses the reference tree and marks every object encountered. In the clear phase, the unmarked object is released, and the memory obtained after releasing the object is returned to the executing program. In the Java virtual machine, the cleanup step must include the termination of the object.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>