JVM garbage collection (object termination mechanism)

Posted by lostincoding on Sun, 07 Nov 2021 22:28:57 +0100

1. What is the object termination mechanism?

  • The Java language provides an object finalization mechanism to allow developers to provide custom processing logic before objects are destroyed
  • When the garbage collector finds that no reference points to an object, it will clear the object in the garbage collection. Before the garbage collector collects the object, it will call the finalize() method of the object
  • We found that the finalize() method can be overridden in subclasses, so we can use this overridden method to release resources or clean up when objects are recycled, such as closing files, sockets and database connections
  • Functionally, the finalize() method is similar to the destructor in C + +, but Java adopts the automatic memory management mechanism based on garbage collector, and they are different in essence

2. Details of object termination

  • The finalize() method will only be called once in an object's life cycle (even if it has been resurrected)
  • We developers should remember not to actively call the finalize() method of an object, but should leave it to the garbage collection mechanism to call
  • Because in the finalize() method, we can cause the object to resurrect, that is, we don't let the garbage collector recycle, which will affect the work of the garbage collector itself
  • Because the execution time of the finalize() method is not guaranteed, it is completely determined by the GC thread, that is, if GC does not occur, the finalize() method will never have a chance to execute
  • Because a bad finalize() method will seriously affect the performance of GC, it is not recommended to call it yourself

3. Three life states of objects

Due to the existence of the finalize() method, objects in the virtual machine generally have three possible states

If an object cannot be accessed from all root nodes, it means that the object is no longer used. In general, this object needs to be recycled. But in fact, they are not "must die". At this time, they are temporarily in the "Probation" stage. Because an unreachable object may "revive" itself under certain conditions, if so, its recycling is unreasonable

  • Touchable state: this object can be reached from the GC Roots root node
  • Revivable state: all references of the object have been released, but the object may be revived in the finalize() method
  • Untouchable state: if an object's finalize() is called and found not to be revived, it will enter an untouchable state. An untouchable object cannot be revived again because finalize() will only be called once

4. Object recovery determination process

To determine whether an object A is recyclable, it needs to go through the marking process at least twice

  • If there is no reference chain from object A to GC Roots, it is marked for the first time
  • If object A does not override the finalize() method, or the finalize() method has been called by the virtual machine, the virtual machine will be regarded as "not necessary to execute", and object A will be determined as inaccessible
  • If object A rewrites the finalize() method and has not been executed, object A will be inserted into the queue of F-Queue, and then its finalize() method will be triggered by the low priority Finalizer thread automatically created by the virtual machine
  • After object A is inserted into the queue of F-Queue, GC will mark all objects in the queue for the second time
  • If object A does not establish A connection with any object in the reference chain in the finalize() method, object A will be determined to be inaccessible at the second marking
  • If object A establishes A connection with any object in the reference chain in the finalize() method, object A will be determined as A resurrectable state at the second marking. However, when the object does not have A reference again, the finalize() method will not be called again and will be directly determined as an inaccessible state

5. Object recycling program demonstration

public class CanReliveObj {
    public static CanReliveObj obj;

	// Override the finalize method (second token)
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("Call the current class override finalize()method");
        obj = this;
    }

    public static void main(String[] args) {
        try {
            obj = new CanReliveObj();

            obj = null;
            System.gc(); // First mark
            System.out.println("1st time gc");
            Thread.sleep(2000);
            if (obj == null) {
                System.out.println("obj is dead");
            } else {
                System.out.println("obj is still alive");
            }
			
            obj = null;
            System.gc();
            System.out.println("2nd time gc");
            Thread.sleep(2000);
            if (obj == null) {
                System.out.println("obj is dead");
            } else {
                System.out.println("obj is still alive");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

When the finalize method overridden above is cancelled

When the finalize method overridden above is added

6. What is GC Roots?

What is the GC Roots mentioned above? It is a collection of root search objects judged by the garbage collector during garbage collection. How can I use the tool to view the GC Roots in the code?

Write test code

public class GCRootsTest {
    public static void main(String[] args) {
        List<Object> numList = new ArrayList<>();
        Date birth = new Date();

        for (int i = 0; i < 100; i++) {
            numList.add(String.valueOf(i));
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Data added...");
        new Scanner(System.in).next();
        numList = null;
        birth = null;

        System.out.println("The object has been left empty...");
    }
}

Get Dump file of heap memory

  • Command line mode

    # View current process
    jps
    # Generate dump file
    jmap -dump:format=b,live,file=test1.bin process ID
    

  • Tool export method

    Using the JVisualVM tool


Analyze dump files using tools

  • MAT tool

    MAT, short for Memory Analyzer, is developed by Eclipse. It is a powerful Java heap Memory Analyzer, which is used to find memory leaks and view memory consumption. Download address: http://www.eclipse/org/mat/

  • Jpprofiler tool

Topics: Java jvm