1. The significance of the garbage recycling mechanism A notable feature of the Java language is the introduction of a garbage collection mechanism, which solves the most troublesome memory management problem for C++ programmers, so that Java programmers no longer need to consider memory management when writing programs. Due to the garbage collection mechanism, objects in Java no longer have the concept of "scope", only the reference of the object has a "scope".Garbage collection can effectively prevent memory leakage and effectively use idle memory.
ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Algorithms in garbage collection mechanisms The Java language specification does not explicitly specify which garbage collection algorithm to use in the JVM, but any garbage collection algorithm generally needs to do two basic things: (1) find useless information objects; (2) Reclaim the memory space occupied by useless objects, so that the space can be used again by the program.
1. Reference Counting Collector 1.1 Algorithm analysis
Reference counting is an early strategy in garbage collectors. In this approach, there is a reference count for each object instance in the heap. When an object is created and the object instance is assigned to a variable, the variable count is set to 1. When any other variable is assigned as a reference to this object, the count is added by 1 (a = b, then the counter of the object instance referenced by b is +1), but when a reference to an object instance has exceeded its lifetime or is set to a new value, the reference counter of the object instance is subtracted by 1. Any instance of an object with a reference counter of 0 can be collected as garbage. When an object instance is garbage collected, the reference counter of any object instance it references is minus 1. 1.2 Advantages and disadvantages Merit:
The reference count collector can be executed very quickly, interwoven into the program's run. It is advantageous for real-time environments where programs need not to be interrupted for long periods of time. Shortcoming:
Circular references cannot be detected. *If the parent object has a reference to a child object, the child object in turn references the parent object. In this way, their citation count can never be 0. 1.3 The reference counting algorithm cannot solve the circular reference problem, for example:
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main { public static void main(String[] args) { MyObject object1 = new MyObject(); MyObject object2 = new MyObject(); object1.object = object2; object2.object = object1; object1 = null; object2 = null; }} The last two sentences assign object1 and object2 to null, which means that the objects pointed to by object1 and object2 can no longer be accessed, but because they refer to each other, their reference counters are not 0, so the garbage collector will never recycle them.
2. Tracing Collector or mark and sweep algorithm 2.1 Root search algorithm
The root search algorithm is introduced from graph theory in discrete mathematics, the program regards all reference relationships as a graph, starting from a node GC ROOT, looking for the corresponding reference node, after finding this node, continuing to look for the reference node of this node, when all the reference nodes are searched, the remaining nodes are considered to be unreferenced nodes, that is, useless nodes. java that can be used as GC Root 1. Objects referenced in the virtual machine stack (local variables table) 2. The object referenced by the static attribute in the method area 3. The object referenced by the constant in the method area 4. Referenced Objects in the Local Method Stack (Native Objects)
2.2 Schematic diagram of tracing algorithm
![]()
2.3 Analysis of marker-clearing algorithm
The tag-purge algorithm scans from the root collection, marks the surviving objects, and then scans the entire space for untagged objects to recycle, as shown in the figure above. The tag-purge algorithm does not need to move objects, and only processes non-surviving objects, which is extremely efficient when there are many surviving objects, but because the tag-purge algorithm directly recycles non-surviving objects, it will cause memory fragmentation.
3. Compacting algorithm or label-finishing algorithm
![]()
The tag-finish algorithm uses the same method as the tag-clear algorithm to label objects, but it is different when purging, after reclaiming the space occupied by non-surviving objects, it will move all surviving objects to the free space on the left end and update the corresponding pointer. The tag-finish algorithm is based on the tag-purge algorithm and moves objects, so it is more expensive, but it solves the problem of memory fragmentation. In the implementation of collectors based on the Compacting algorithm, handles and handles tables are generally added.
4. Copying Algorithm (Compacting Collector)
![]()
The algorithm is proposed to overcome the overhead of the handle and solve the garbage collection of heap debris. When the object is full, the garbage collection based on the copying algorithm scans the active object from the root set, and copies each active object to the free face (so that there are no free holes between the memory occupied by the active object), so that the free surface becomes the object face, the original object face becomes the free face, and the program allocates memory in the new object face. A typical garbage collection based on the coping algorithm is the stop-and-copy algorithm, which divides the heap into object faces and free area faces, and the program pauses execution during the switching between object faces and free area faces.
5. Generational Collector
![]()
The generational garbage recycling strategy is based on the fact thatThe life cycle of different objects is different。 Therefore, objects with different life cycles can adopt different recycling algorithms to improve recycling efficiency.
Young Generation 1. All newly generated objects are placed in the younger generation first. The goal of the younger generation is to collect those objects with a short life cycle as quickly as possible.
2. The new generation memory is divided into one Eden region and two survivor (survivor0, survivor1) zones according to the ratio of 8:1:1. One Eden zone, two Survivor zones (in general). Most of the objects are spawned in the Eden area. When the survivor0 area is also full, the eden area and the survivor 0 area are copied to another survivor1 area, and then the eden and survivor0 area are emptied, and then the survivor0 area is empty, and then the survivor0 area and the survivor1 area are exchanged. That is, keep the survivor1 area empty, and so on.
3. When the survivor 1 area is not enough to store the surviving objects of eden and survivor0, the surviving objects are stored directly to the old era. If the old age is also full, it will trigger a full GC, that is, the new generation and the old generation will be recycled
4. The GC of the new generation is also called Minor GC, and the frequency of MinorGC is relatively high (it is not necessarily triggered when the Eden area is full)
Old Generation
1. Objects that are still alive after experiencing N garbage recycling in the younger generation will be placed in the older generation. Therefore, it can be considered that the old generation is stored in some objects with a long life cycle.
2. The memory is also much larger than that of the new generation (the approximate ratio is 1:2), when the memory of the old age is full, the Major GC is triggered, that is, Full GC, the frequency of Full GC is relatively low, the survival time of the old age object is relatively long, and the survival rate mark is high.
Permanent Generation Used to store static files, such as Java classes, methods, etc. Persistent generations have no significant impact on garbage collection, but some applications may dynamically generate or call some classes, such as Hibernate, etc., and in this case, a relatively large persistent generation space needs to be set to store these new classes during the runtime.
3. GC (Garbage Collector)Collectors used by the new generation collectors: Serial, PraNew, Parallel Scavenge Collectors used by Old Age Collectors: Serial Old, Parallel Old, CMS
![]()
Serial collector (replication algorithm) The new generation of single-threaded collectors, marking and cleaning are single-threaded, with the advantage of being simple and efficient.
Serial Old Collector (Label-Finish Algorithm) Old Age Single Thread Collector, Old Age version of Serial Collector.
ParNew collector (stop-copy algorithm) The new generation collector can be considered a multi-threaded version of the Serial collector, which has better performance than Serial in a multi-core CPU environment.
Parallel Scavenge Collector (Stop-Copy Algorithm) Parallel collectors for high throughput and efficient CPU utilization. The throughput is generally 99%, and the throughput = user thread time / (user thread time + GC thread time). It is suitable for scenarios such as background applications that do not require high interaction correspondingly.
Parallel Old Collector (Stop-Copy Algorithm) An older version of the Parallel Scavenge collector, a parallel collector, with throughput priority
CMS (Concurrent Mark Sweep) Collector (Mark-Clean Algorithm) High concurrency, low pause, pursuing the shortest GC recovery pause time, high CPU usage, fast response time, short pause time, and multi-core CPU pursuing high response time
4. The implementation mechanism of GCSince the object has been processed in different generations, the area and time of garbage collection are also different. There are two types of GC: Scavenge GC and Full GC.
Scavenge GC Normally, when a new object is generated and fails to apply for space in Eden, the Scavenge GC will be triggered, which will GC the Eden area, clear non-surviving objects, and move the surviving objects to the Survivor area. Then sort out the two zones of Survivor. GC in this way is performed on the Eden area of the younger generation and does not affect the older generation. Because most objects start from the Eden area, and the Eden area is not allocated very much, the GC of the Eden area is carried out frequently. Therefore, it is generally necessary to use fast and efficient algorithms here to make Eden free as soon as possible.
Full GC Organize the entire pile, including Young, Tenured, and Perm. Full GC is slower than Scavenge GC because it requires recycling the entire heap, so the number of Full GCs should be reduced as much as possible. A large part of the JVM tuning process is the tuning of FullGC. Full GC can be caused by the following reasons: 1. Tenured is written full 2. Perm is written full 3. System.gc() is displayed as a call 4. The domain allocation strategy of Heap changes dynamically after the last GC
5. Java with GC will also have memory leakage problems1. The use of static collection classes such as HashMap, Vector, etc. is the most prone to memory leakage, and the life cycle of these static variables is the same as that of the application, and all objects cannot be released, because they will always be applied by Vector and others. Static Vector v = new Vector(); for (int i = 1; i<100; i++) { Object o = new Object(); v.add(o); o = null; } In this example, there is a reference v for the Vector object and a reference o for the Object object in the code stack. In the For loop, we keep generating new objects, then adding them to the Vector object, and then nullifying the o reference. The question is, when the o reference is nullified, if GC occurs, can the Object object we created be recycled by GC? The answer is no. Because when GC tracks references in the code stack, it finds v references, and if you continue to trace down, you will find that there are references to Object objects in the memory space pointed to by v references. This means that even though the o reference has been emptied, there are still other references to the Object object that can be accessed, so the GC cannot free them. If after this loop, the Object object has no effect on the program, then we assume that the Java program has a memory leak. 2. Various connections, database connections, network connections, IO connections, etc. do not show the call close to close, and are not recycled by GC, resulting in memory leakage. 3. The use of listeners may also cause memory leakage when the listener is not deleted while releasing the object.
|