This is the 22nd day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Introductions to the 0.

Java garbage collection is a series of operations on the stack, heap, and constant areas of the JVM to reclaim (format) the memory occupied by objects that are no longer being used, rationalizing the use of memory resources.

1. Is the object dead?

The first thing you need to do to do garbage collection is determine whether an object is no longer referenced. There are two common algorithms.

  • Reference counting algorithm
  • Accessibility analysis algorithm

The reference counting algorithm is relatively simple. It’s simply adding a reference counter to the object that increments by 1 every time it’s referenced; When a reference is invalid, the counter value is reduced by 1. If the count is 0 at some point in time, the object is no longer referenced and can be reclaimed.

But the reference-counting algorithm has a fatal problem, which is that it is difficult to solve the problem of bidirectional reference (circular reference). For instance,


ObjA objA = new ObjA();
ObjB objB = new ObjB();

objA.next = objB;
objB.next = objA;

objA = null;
objB = null;

Copy the code

In this case, the reference count for both objA and objB objects is not zero, but there is no way to use objA and objB’s objects. Because of circular references, the reference count is not zero and cannot be GC.

Because of this problem with reference counting algorithms, most current JVMS use reachability analysis algorithms instead of this approach.

The core idea of the reachable analysis algorithm is to search all reachable nodes through a series of objects called “GC Roots” as the starting nodes. If an object is unreachable, the object is unavailable. It can be recycled.

Objects that can be used as GC Roots in Java include:

  • Object referenced in the virtual machine stack
  • The object referenced by the class static property in the method area
  • The object referenced by the constant in the method area

2. The finalize () method

The Finalize () method is a method that is called before objects are collected. However, the call of finalize() method is not deterministic.

When an object is marked as unreachable after the reachability analysis, it will determine whether the current object overwrites finalize() method and whether finalize() method of objects has been executed. If it is not overwritten or has been executed, it will not be executed and the object will be recycled.

If it is necessary to execute the Finalize () method, the object will be put into a low-priority Queue in an F-queue for execution. The GC then performs a reachability analysis on the objects in the F-queue again.

So, if an object can be resurrected again in finalize(), reassign its this pointer to a reference to a reachable object.

The following code demonstrates how to revive objects ina Finalize () method. (PS: Although this can be done, I have never encountered such a scenario.)

public class MyGC { private static GCTest gcTest = null; private static class GCTest{ public String name; public GCTest(String name) { this.name = name; } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println(" Finalize to be executed "); // Assign references to other reachable GC Roots gcTest = this; } } public static void main(String[] args) { gcTest = new GCTest("myGc"); // GCTest object unreachable GCTest = null; System.gc(); // wait 5s try {thread.sleep (5000); } catch (InterruptedException e) { e.printStackTrace(); } // The object is reachable system.out.println (gctest.name); }}Copy the code

We define a MyGC class, which has a static attribute and its type is an inner class (GCTest). GCTest overrides finalize() and saves itself in Finalize () by assigning its reference to the external attribute. So in the main method, even though we show that we set the gcTest object to null, we can still reference it.

In terms of object references, after Java 1.2, object references fall into four broad categories:

  • Strong Reference

    References such as “Object obj=new Object()” will never be reclaimed by the garbage collector as long as the strong reference exists.

  • Soft Reference

    Objects associated with soft references are listed in the collection scope for a second collection before the system is about to run out of memory

  • Weak Reference

    Objects associated with weak references can only survive until the next garbage collection occurs. When the garbage collector works, objects associated only with weak references are reclaimed regardless of whether there is currently enough memory

  • Phantom Reference

    It’s the weakest kind of relationship. The existence of a virtual reference does not affect the lifetime of an object, nor can an object instance be obtained through a virtual reference. The sole purpose of setting a virtual reference association for an object is to receive a system notification when the object is reclaimed by the collector.