Android GC (garbage collection) summary

foreword

Garbage collection generally needs to suspend the execution of all threads, called stop-the-world. GC optimization is basically to reduce the number of pauses and pause time.

1. Where to recycle the garbage

The memory of the JVM is roughly divided into five areas, the program counter, the virtual machine stack, the local method stack, the heap, and the method area.

program counter

As the name implies, it is similar to the PC register, each thread exists independently, and its life cycle is consistent with the thread. Indicates the currently executing method, with little memory, negligible, and no garbage.

virtual machine stack

Stack space, which exists independently for each thread, saves method parameters or references to objects within the method. At the end of the life cycle, for example, the memory will be released after the method is executed, so no garbage management is required.

native method stack

Similar to the virtual machine stack, it corresponds to the native method. No garbage management required.

heap

The actual storage area of ​​the object, such as new a local variable in the method, open up memory in the heap, and save the reference in the virtual machine stack. It is also the most important area for waste management.

method area

Class files and constants (JDK7 starts the string constant pool in the heap area) storage area, which belongs to the scope of garbage management.

2. Determine what is garbage

There are two main algorithms, reference counting method and reachability analysis method (root search algorithm). Almost all garbage collectors use reachability analysis.

reference counting

Record the number of references for each reference. When the number of references is 0, it means it is garbage and should be cleaned up.
advantage:

  1. easy to implement
  2. When the reference is reduced to 0, the memory is reclaimed in real time, and the memory utilization rate is high
  3. Recycling operations can run concurrently without pausing application threads

Disadvantages:
4. Unable to resolve circular references, such as a refers to b, and b refers to a. Both are garbage but will not be cleaned up (too fatal)
5. Space overhead: Each object needs extra space to store the number of references
6. Speed ​​overhead: Each reference modification requires additional instructions, and in multi-threaded cases, lock guarantees are required atomic operation

Reachability analysis method (root search algorithm)

Determine the root object (GC ROOT), and traverse along the root object. Anything that is directly or indirectly referenced by the root object is not garbage, and the rest is garbage.
GC ROOT objects in Java include:
7. Objects referenced in the virtual machine stack (local variable table)
8. Objects referenced by static properties in the method area
9. Objects referenced by constants in the method area
10. Objects referenced in the local method stack (Native object)

Advantages of the algorithm:
11. There is no circular reference problem
12. There is no space and runtime overhead of reference counting

Disadvantages of the algorithm:
13. Low memory utilization (before the GC reclaims the memory, the memory occupied by garbage objects cannot be reused
14. The design is complex, if you need to support concurrent recovery, you need additional data structure support
15. PauseTime: root set enumeration and reference tracing The process generally needs to suspend the application thread at least once, and most collectors need to suspend 2-3 times

3. How to recycle garbage

Generational recycling

Young generation : Most of the newly created objects will be allocated here. Since most of them become unreachable soon after creation, many objects are created in the young generation and then "disappear". The process of objects "disappearing" from this area is called Minor GC.
The new generation can be subdivided into three spaces: Eden, survivor0, and survivor1. The default ratio is 8:1:1.

Old generation (Old generation) :

  1. The object is relatively large, and it is directly allocated in the old generation when it is allocated.
  2. Many times (default 15) survived the young generation cycle and will be copied to the old generation.
  3. Dynamic object age determination.
    If the sum of the sizes of all objects accumulated from a low age in the Survivor area is greater than half of the space in the Survivor area, objects whose age is greater than or equal to the critical age can directly enter the old age.
  4. Space Allocation Guarantee.
    Before JDK 6 Update 24: Before Minor GC occurs in the young generation, the virtual machine checks whether the maximum available contiguous space in the old generation is greater than the total space of all objects in the new generation. If it is larger, the Minor GC can ensure safety this time. If it is not established, the virtual machine will allow the guarantee failure according to the setting value of the -XX:HandlePromotionFailure parameter. If it is allowed, check whether it is larger than the average size of objects promoted to the old generation in the past. If it is larger, perform Minor GC (risky, possibly old Full GC is forced due to insufficient space in the era to allocate objects in the new generation), if it is less than or the setting does not allow it, then perform a Full GC instead.
    After JDK 6 Update 24: XX: HandlePromotionFailure has this parameter, but it does not work. The rule is that as long as the maximum available continuous space in the old generation is greater than the total space of all objects in the new generation or the average size of previous promotions, Minor GC will be performed, otherwise Full GC

The old generation area allocates more space than the young generation. Also because of its relatively large space, the number of GCs that occur in the old generation is much less than that in the new generation. The process of objects disappearing from the old generation is called: Major GC or Full GC.

Permanent generation (Permanent generation) is also called method area (Method area): used to save class constants and string constants. Note that this area is not used to store objects that have survived from the old generation, and GC may also occur in this area. GC events that occur in this area are also counted as Major GC. It's just that the conditions for GC to occur in this area are very strict, and the following three conditions must be met before they can be recycled:
1. All instances are recycled
2. The ClassLoader that loads the class is recycled
3. Class objects cannot be accessed through any means (including reflection)

mark-and-sweep algorithm

After the garbage is determined, it is directly recycled and cleared. The advantage is that the implementation is simple and the GC time is short. The disadvantage is that it generates a lot of memory fragmentation. The schematic diagram is as follows.
mark-and-sweep algorithm

tag copy algorithm

Divided into two spaces, one active and one idle. Determine the surviving objects in the active space, copy all of them to the free space, and reclaim all the active space. Then the roles of the two are reversed, active becomes idle, and idle becomes active.
The advantage is that there is no memory fragmentation problem, and the disadvantage is that half of the space is wasted (Eden in the new generation is always used as the active space, and survivor0 and survivor1 exchange roles after each garbage collection. So actually only one-tenth of the space is wasted) and the copying of objects overhead. The schematic diagram is as follows.
tag copy algorithm

Mark Compression Algorithm

Mark the surviving objects, and then copy and organize the surviving objects in one direction (left end). This way the remaining space is contiguous. The advantage is also that there is no memory fragmentation problem. Compared with the mark copy algorithm, there is no space waste, but the object collation is more time-consuming than direct copy. The schematic diagram is as follows.
Mark Compression Algorithm

4. The main garbage collector

The above is the algorithm or idea mainly involved in garbage collection, and the following is the specific implementation of each enterprise or project.

Serial

A serial collector.
The Serial collector is the most basic and oldest collector in the Java virtual machine. Before JDK1.3, it was the only choice for the new generation collector of the Java virtual machine. At present, it is also the default garbage collector for ServerVM with 4 cores and 4GB or less under ClientVM. The Serial collector does not only use one CPU for collection, but when the JVM needs to perform garbage collection, it needs to suspend all user threads until the collection ends.
Algorithm used: Mark Copy Algorithm

SerialOld

SerialOld is the old age collector version of the Serial collector. It is also a single-threaded collector. This collector is currently mainly used in Client mode. If it is in Server mode, it has two main uses: one is to use it with the Parallel Scavenge collector in JDK1.5 and earlier versions, and the other is to serve as a backup plan for the CMS collector. If the CMS has a Concurrent Mode Failure , then SerialOld will serve as the backing collector.
Algorithm used: Tagging-Collating Algorithm

ParNew

ParNew is actually a multi-threaded version of the Serial collector. Except for the Serial collector, only it works with the CMS collector. ParNew is the preferred new generation collector for many JVMs running in Server mode. But in the case of a single CPU, its efficiency is far lower than the Serial collector.
Algorithm used: Mark Copy Algorithm

ParallelScavenge

ParallelScavenge is also known as the throughput priority collector, which is similar to the ParNew collector and is a new generation collector.
Use Algorithm: Copy Algorithm

ParallelOld

ParallelOld is a parallel collector. Like SerialOld, ParallelOld is an old generation collector, which is a collector that prioritizes throughput in the old generation. This collector was only provided after JDK1.6. Before that, ParallelScavenge could only choose SerialOld as its old age collector, which seriously slowed down the overall speed of ParallelScavenge. After the emergence of ParallelOld, the "throughput priority" collector is worthy of its name.
Algorithm used: Tagging-Collating Algorithm

CMS (the default collector from Android4.4 to Android8)

An old generation collector, the full name of Concurrent Low Pause Collector (also known as Concurrent Mark Sweep), is a new GC collector referenced in the late JDK1.4, which has been further improved in JDK1.5 and 1.6. It is a collector where response time is more important than throughput. It is very suitable to use CMS when the server response speed is required to be high.
A major feature of CMS is that two short pauses are used to replace the long pauses in serial or parallel markup algorithms.
Algorithm used: mark-clean up
the execution process of CMS as follows:
· Initial mark (STW initial mark)
At this stage, the virtual machine needs to stop the executing application thread, the official name is STW (Stop Tow World). This process scans directly related objects from the root object and marks them. This process will be completed quickly.
· Concurrent marking (Concurrent marking)
This phase follows the initial marking phase, and continues to trace the marking downwards on the basis of the "initial marking". Note that this is a concurrent mark, which means that user threads can execute concurrently with GC threads, and user threads will not be suspended at this stage.
Concurrent precleaning (Concurrent precleaning)
This stage is still concurrent, and the JVM looks for objects that enter the old age when the "concurrent mark" stage is being executed (maybe at this time, objects will be promoted from the new generation to the old age, or be allocated to old generation). By rescanning, reduce the work of "re-marking" in one stage, because the next stage will STW.
· Remark (STW remark)
This stage will pause the executing application thread again, restart the root object to start searching and mark the objects missed in the concurrent stage (caused by the update of the object state after the concurrent mark stage ends), and process object association. This time will take longer than "initial marking", and this stage can be marked in parallel.
· Concurrent sweeping (Concurrent sweeping)
This phase is concurrent, and the application thread and the GC sweeping thread can be executed concurrently.
Concurrent reset (Concurrent reset)
This stage is still concurrent, resets the data structure of the CMS collector, and waits for the next garbage collection.
Disadvantages of CMS:
1. Memory fragmentation. Due to the use of the mark-sweep algorithm, memory fragmentation occurs in the memory space. However, the CMS collector has made some small optimizations, which is to summarize the unallocated space into a list. When a JVM needs to allocate memory space, it will search this list to find a qualified space to store this object. However, the problem of memory fragmentation still exists. If an object needs 3 contiguous spaces for storage, due to memory fragmentation, if such a space cannot be found, it will lead to Full GC.
2. Need more CPU resources. Due to the use of concurrent processing, in many cases, GC threads and application threads are executed concurrently, which requires more CPU resources and sacrifices a certain amount of throughput.
3. More heap space is required. Because the application thread is still executing during the CMS marking phase, there will be a problem of continued allocation of heap space. In order to ensure that the CMS still has space to allocate to newly added objects before reclaiming the heap space, a part of the space must be reserved. By default, CMS starts garbage collection when the old generation space is 68% used. This threshold can be set by -XX:CMSinitiatingOccupancyFraction=n.

CMS In Android applications, when object allocation fails due to fragmentation or the application enters the background, it will perform compression to solve the problem of memory fragmentation.

Sticky CMS (sticky-CMS)

sticky-CMS is ART's non-moving generational garbage collector. It only scans the parts of the heap that were modified since the last GC, and can only reclaim objects allocated since the last GC.

CC(Concurrent Copying)

Android8 starts the default garbage collector

CC supports the use of a touch pointer allocator called "RegionTLAB". This allocator can allocate a thread-local allocation buffer (TLAB) to each application thread, so that an application thread can allocate an object from its TLAB by simply touching the "top of the stack" pointer without any synchronization .
CC performs heap defragmentation by concurrently copying objects without pausing application threads. This is achieved with the help of read barriers, which intercept reference reads from the heap without any intervention from the application developer.
The GC has only one short pause, which is constant in time for the heap size.
In Android 10 and higher, CC is extended to generational GC. It enables easy recycling of short-lived objects, which typically become unreachable very quickly. This helps improve GC throughput and significantly delays the need to perform a full heap GC.

GarbageFirst(G1)

JDK1.7 introduced, 1.9 becomes the default collector

G1 is a server-oriented garbage collector. It is mainly aimed at multi-core processors with large memory machines. It can meet the pause time of gc and guarantee the throughput. Generally, G1 is recommended for more than 8G. G1 discards the strict generation in the previous heap. Memory division. G1's processing of the heap model is converted into the following figure, which divides the entire heap memory into small independent regions (Regions). The JVM can have up to 2048 Regions, and the parameter -XX:G1HeapRegionSize can also be used to specify Regions It is generally not recommended to specify the size. Although G1 still has generational memory division, it discards continuous generations. They can be some discontinuous Region collections. Because of this, the function of each Region will change, such as A Region was considered to be the young generation before, and it becomes the old generation after garbage collection.
The mark-organization algorithm is used as a whole, and the copy algorithm is used locally

GarbageFirst

ZGC

An up-to-date garbage collector. JDK11 introduced (experimental nature), JDK15 became regular.
Design goal:
The maximum pause time does not exceed 10ms: The reason why it can be controlled below 10ms is that its pause time is mainly related to Root scanning, but has nothing to do with the number of roots and the size of the heap.
In the worst case, throughput will drop by 15% compared to G1

5. Reference blog post

Java performance optimization JVM GC (garbage collection mechanism)
JVM garbage collection algorithm and ART CC collector implementation overview
Android Runtime (ART) and Dalvik

Guess you like

Origin blog.csdn.net/Welcome_Word/article/details/124051691