JVM garbage collection mechanism reference notation and reachability analysis

JVM Garbage Collection Mechanism Reference Counting Algorithm and Reachability Analysis Algorithm


Here is a more detailed analysis of the reference counting algorithm

 

First you need to determine which memory needs to be reclaimed

Since the thread-private virtual machine stack, Native stack, and program counter all live and die side by side with the thread, they are allocated at the beginning of the thread, and the thread-private memory is reclaimed at the end of the thread. Only the question of how to recycle is left. Save it for later.

The class information in the method area is to be recycled, and the judgment is very strict. The place where garbage collection occurs most frequently should be in the heap. Almost all object instances are stored in the heap. The first thing to do is to determine which instances need to be recycled.

 

Judging whether the instance is still alive - reference counting algorithm and reachability analysis method

 

In-depth analysis of the reference counting algorithm:

The basic implementation is: each object has a reference counter, when a place refers to the object, the counter +1 , when a reference to the object expires, the counter -1 . A value of 0 means that the object can no longer be used.

This implementation is efficient and simple in design, but it is difficult to solve the problem of circular references between objects.

So what is a reference to that object, and when does the reference to that object expire?

The reference object is also easier to understand, that is, when a variable gets a reference to an instance in the heap, it is counted as a reference.

Reference invalidation means that the object that originally had a reference to an instance address in the heap loses the reference, which is counted as reference invalidation.

Here is an example to illustrate that there is very little information on the Internet. I found an answer from Zhihu that is clearer and makes sense. Here is a simple arrangement of the author's ideas:

publicstaticvoid
main(String[] args) {
 GcObject obj1 = new GcObject(); //Step1
GcObjectobj 2 = new GcObject();//Step2
obj1.instance= obj2; //Step3
obj2.instance= obj1;////Step4
obj1 = null; // Step5
obj2= null; //Step6


}



step1: newing a GcObject() is equivalent to assigning a reference to the instance (for the time being called instance 1 ) to obj1  instance 1 in the heap by reference count + 1 

step2: newing a GcObject() is equivalent to assigning a reference to the instance (for the time being called instance 2 ) in the heap to obj2  instance 2 is referenced by count +1 

step3: Assign obj2   to the obj1.instance property and obj2 is a reference to instance 2 , so instance 2 is referenced by +1 

step4: Assign obj1   to the obj2.instance property and obj1 is a reference to instance 1 , so instance 1 is referenced by +1 

step5: obj1 no longer references instance instance 1 reference invalidation count -1 

step6: obj2 no longer references instance instance 2 reference invalidation count -1  


At this point, instance 1 and instance 2 can no longer be referenced, whether obj1 or obj2 or their instance is no longer a reference to the instance with = null .

But at this time , the counter values ​​of instance 1 and instance 2 are both 1 , and a memory leak occurs.

A hypothetical situation: here is not a mutual circular reference between objects, what would it be?

In other words, why do problems with reference counting algorithms occur when objects are cyclically referencing each other?

The original author left this question to the reader to solve for himself.


obj3= obj2; //Step3*


obj4= obj1;//Step4*


obj1 = null; // Step5 *


obj2= null; //Step6*



step3*: Assign obj2   to obj3 and obj2 is a reference to instance 2 , so instance 2 is referenced by +1 

step4*: Assign obj1   to obj4 and obj1 is a reference to instance 1 , so instance 1 is referenced by +1 

step5*: obj1 no longer references instance instance 1 reference invalidation count -1 

step6*: obj2 no longer references instance instance 2 reference invalidation count -1 



But note that at this time, the references of obj3 and obj4 to instance 1 and instance 2 are still retained, and are not emptied with the operation of obj1 and obj2 = null , so it is correct that the counters of instance 1 and instance 2 are both 1 at this time of.



It can be seen that the reference counting algorithm is still very reliable in many cases, so a considerable number of technologies also use the reference counting algorithm.



Reference: The original author @Gityuan answered: https://www.zhihu.com/question/21539353



Reachability Analysis Algorithm:

This is the algorithm currently used by the JVM .

The algorithm uses a series of GC Roots objects as a starting point, searches downward from these objects, and connects to the surviving objects. If an object cannot be connected to any GC Roots , the object will be judged to be dead.


GC Roots include:


1. Objects referenced in the virtual machine stack

2. Objects referenced by static properties in the method area

3. Objects referenced by constants in the method area

4. Objects referenced by native methods in the native method stack

The above is mentioned in the book, and the other online information says that there is another list of surviving Thread class objects, Class classes, etc., I feel that the book at hand is only different in the classification method of GC Roots and the statement on the Internet , which are actually similar things. For example, the objects referenced in the virtual machine stack may include some thread objects.



 



 



 



 



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325659386&siteId=291194637