Damn it! The GC garbage collection mechanism is so simple! You still don’t understand this, I was there! Just eat this computer screen

Preface

As an Android developer, if you want to advance to the advanced level, memory management is often an unavoidable link, and the 垃圾回收 以下简称GC(Garbage Collection)mechanism, as the most important part of memory management, is something we must master. I will share today for the next garbage collection and recycling strategies generational understanding.

table of Contents


  • 1. Background

  • 2. Two recycling mechanisms

    • 2.1. Reference counting
    • 2.2. Accessibility analysis
  • 3. Recovery Algorithm

    • 3.1. Mark removal algorithm
    • 3.2. Copy Algorithm
    • 3.3. Marker compression algorithm
  • 4. Generational recycling strategy

    • 4.1. Cenozoic
    • 4.2. Old generation
  • 5. Four major citations


1. Background

Generally speaking, in the process of programming, we will continue to write data into the memory, and these data must be cleared from the memory in time when they are used up, otherwise it will be triggered OutOfMemory(内存溢出), so every programmer must follow this principle. 听说(我也不懂C语言~)在C语言阶段,Garbage needs to be manually collected by programmers, and we Javaer are relatively happy because JVM exists GC机制, which means that JVM will help us clean up garbage automatically, but happiness comes at a price, because there will always be some garbage. GC算法This phenomenon is also called the avoidance of objects by 内存泄漏mistakes, so only by mastering the GC mechanism can we avoid writing programs that leak memory.

2. Two recycling mechanisms

2.1 Reference counting

What is reference counting? Figuratively A a = new A(), the code A referenced object is a held, this time reference count is +1 , if a references set to null i.e., a = nullwhich is the object A reference count is changed to 0 , the algorithm detects the GC A An object reference count of 0 will be recycled. Very simple, but there are some drawbacks to reference counting

The scenario is as follows:

A a = new A();
B b = new B();
a.next = b;
b.next = a;
a = null;
b = null;

Will objects A and B be recycled after the above code is executed ? It seems that the references have been set to null , but in fact the next of a and b respectively hold each other's references, forming a situation of mutual holding of references, causing A and B to become garbage objects and cannot be recycled. Some students may say that the memory leak is too easy to see, and it is not enough to set the respective next to empty before a and b are empty. Well, that's true, but it is difficult to see at a glance the huge business logic memory leak in actual business. So JVM later abandoned reference counting and adopted reachability analysis.

2.2 Accessibility analysis

Reachability analysis is actually a concept in mathematics. In the JVM, some special references are regarded as GcRoot , and objects that can be accessed through GcRoot will not be regarded as garbage objects. In other words, if an object is directly or indirectly held by GcRoot , then the object will not be treated as a garbage object. Use a picture to show that it looks like this:

The picture A、B、C、D可is visited by GcRoot , so it will not be recycled. E、FIt cannot be visited by GcRoot , so it will be marked as a garbage object. The most typical is G、Hthat although they refer to each other, they cannot be accessed by GcRoot , so they will also be marked as garbage objects. To sum up: reachability analysis can solve the reference count of the object in question refer to each other can not be recycled.

What kind of references can be used as GcRoot ? There are roughly four types as follows:

  • Local variables in the stack
  • Static variables in the method area
  • Constants in the method area
  • Reference object of local method stack JNI

important point

Don't confuse the two concepts of reference and object. Objects actually exist in memory, and reference is just a variable/constant and holds the address of the object in memory.

Let me verify several GcRoot through some code

Local variable

The author uses Android code for debugging, students who don’t understand Android regard it onCreateas a mainmethod.

public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        method();
    }

    private void method(){
        Log.i("test","method start");
        A a = new A();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i("test","method end");
    }

    class A{
        @Override
        protected void finalize() throws Throwable {
            Log.i("test","finalize A");
        }
    }
}

prompt

  • In java, an object is recycled and its finalizemethod is called
  • Garbage collection in the JVM is performed in a separate thread. For better verification effect, add 2000 millisecond delay here

The print result is as follows:

17:58:57.526   method start
17:58:59.526   method end
17:58:59.591   finalize A

The execution time of the method method is 2000 milliseconds, and the object A is recycled immediately after the method ends. So it can be determined that the local variables in the stack can be used as GcRoot

Local method area static variables

public class MyApp extends Application {

    private static A a;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("test","onCreate");
        a = new A();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        a = null;
        Log.i("test","a = null");
    }
}

The print result is as follows:

18:12:35.988   a = new A()
18:12:38.028   a = null
18:12:38.096   finalize A

Create an A object and assign it to the static variable a , and set the static variable a to null after 2000 milliseconds . It can be seen from the log that the object A is immediately recycled after the static variable a becomes empty. So it can be considered that static variables can be used as GcRoot

方法区常量与静态变量验证过程完全一致,关于native 验证过程比较复杂,感兴趣的同学可自行验证。

Verify that the member variable can be used as GcRoot

public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        A a = new A();
        B b = new B();
        a.b = b;
        a = null;
    }

    class A{
        B b;
        @Override
        protected void finalize() throws Throwable {
            Log.i("test","finalize A");
        }
    }

    class B{
        @Override
        protected void finalize() throws Throwable {
            Log.i("test","finalize B");
        }
    }
}

The print result is as follows:

13:14:58.999   finalize A
13:14:58.999   finalize B

It can be seen from the log that both objects A and B have been recycled. Although the B object is held by the b reference in the A object, the member variable cannot be used as GcRoot , so the B object is unreachable and will be treated as garbage.

3. Recovery Algorithm

The previous summary describes the GC mechanism, but the specific implementation still depends on the algorithm. Below I briefly describe several common GC algorithms .

3.1. Mark removal algorithm

Get all the GcRoot and traverse all the objects in the memory. If they can be GcRoot , add a mark, and all the remaining objects will be treated as garbage and cleared.

  • Advantages: simple implementation, high execution efficiency
  • Disadvantages: prone to memory fragmentation (scattered distribution of available memory) , if you need to apply large blocks of contiguous memory may frequently trigger GC

3.2. Copy Algorithm

Divide the memory into two blocks and use only one block each time. First traverse all objects and copy the available objects to another block of memory. At this time, the previous block of memory can be regarded as all garbage. After cleaning, the new block of memory is set as currently available. So repeatedly

  • Advantages: solve the problem of memory fragmentation
  • Disadvantages: The memory needs to be allocated in order, and the available memory becomes half of the original.

3.3. Marker compression algorithm

Get all the GcRoot . GcRoot starts by traversing all the objects in the memory, compressing the available objects to the other end, and then clearing the garbage objects. In fact, time complexity is sacrificed to reduce space complexity

  • Advantages: solve the mark to clear memory fragmentation does not need to copy algorithm memory block
  • Disadvantages: still need to move the object, the execution efficiency is slightly lower.

4. Generational recycling strategy

In the JVM garbage collector it is very busy, if an object survive longer, to avoid duplication of creation / recovery to the garbage collector further burden that can not be sacrificed point memory cache it up? The answer is yes. JVM developed a generational collection policy setting life cycle for each object, the heap memory will be divided into different regions, each to store the object lifecycle. Lifecycle general object have the new generation, old time, permanent-generation (java 8 obsolete) .

4.1. Cenozoic

First look at the schematic diagram of the new generation memory structure:

According to 8:1:1, the new generation memory is divided into Eden, SurvivorA, SurvivorB

New generation memory workflow:

  • When an object is just created, it will be placed in the Eden area. When the Eden area is about to be full, a garbage collection is performed, the currently surviving objects are copied to SurvivorA , and Eden is then emptied
  • When Eden is full the next time, we will do another garbage collection, copy the surviving objects to SurvivorB , and then recycle all the objects of Eden and SurvivorA .
  • When Eden is full again, perform garbage collection again, copy the surviving objects to SurvivorA , and then recycle Eden and SurvivorB objects. This is repeated about 15 times, and the objects that are still alive are placed in the old age area.

The new generation of workflow and replication algorithm scenario is more consistent, is to copy the core, it will use the copy algorithm .

4.2. Old age

According to the previous section, we can see that when an object longer survival time will be credited to old's region. When the old generation area is about to be full, it will do a garbage collection.

So old's region is characterized by live objects, less garbage objects, using markers compressed moving less time algorithm, it does not produce memory fragmentation. So old's region can choose mark compression algorithms to further improve efficiency.

5. Four major citations

In the process of our program development, it is unavoidable to create some relatively large objects, such as those used to carry pixel information in Android Bitmap. A slight improper use will cause memory leaks. If there are a large number of similar objects, the impact on memory is quite large. .

In order to avoid the above situation as much as possible, JVM provides us with four object reference methods: strong reference, soft reference, weak reference, and phantom reference for us to choose from. Let me use a table to make an analogy.

  • The following can be assumed that the subject GcRoot visited of
Reference type Timing of recycling
Strong citation Will never be recycled (default)
Soft reference Reclaim when memory is low
Weak reference It will be recycled the first time the GC is triggered
Phantom reference Will be recycled at any time, there is no practical significance

参考文献:《Android 工程师进阶 34 讲》 第二讲

Conclusion

The article describes the GC mechanism from five aspects .

  • The GC mechanism was born to improve the efficiency of developers
  • Reachability analysis to resolve the reference count issues of mutual references
  • Using different GC algorithms in different scenarios can improve efficiency
  • Generational recycling strategy to further improve GC efficiency
  • Clever use of four references may be solved to some extent, the memory leak

Do you understand? Meow~ If you
understand, why don't you give it to a triple company?

Guess you like

Origin blog.csdn.net/Androiddddd/article/details/110089308