After the Java: linked list head is taken out and used, why can next=null speed up gc??

the following is the source code of the unlinkFirst method in LinkedList
where f is the head of the linked list
it says that f.next = null; is good for gc
I don"t quite understand, f is already ROOT unreachable
must be gc
Why does it help gc? to set its next to null?

    private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCountPP;
        return element;
    }
Aug.16,2021

refer to an article: https://www.javaspecialists.e.

if there is an openjdk source code, you can use the following command to find the time when / / help GC was added and the rev number

hg annotate -ufd src\java.base\share\classes\java\util\LinkedList.java

rev 66ef929d58f2 2009-11-06

< hr >

you can refer to "in-depth understanding of the Java Virtual Machine", the landlord should have this book. Imagine a problem. Gc detects GC Roots. Remember, it's Roots!

GC Roots is made up of multiple Root. Modern JVM uses accurate GC. When a Safepoint capable of triggering a GC pause is reached, the Root of all contexts and global references is not checked. Instead, the object offset and type are calculated through the OopMap data structure. With the help of OopMap, HotSpot can quickly check GC Roots.

according to normal logic, there is no problem with not setting f.next = null, but think about it from another angle.
if I delete an element from the header. Delete the head element again?
then it will form:

f1.next = f2
f2.next = head

f2 is referenced by F1, and F1 is not referenced (regardless of external holdings)

< hr >

after calling unlink, the currently called thread or method does not reach the Safepoint that can trigger a GC pause. Then the f that has just been deleted is not immediately recycled.
when creating a new object at this time:

  1. if there is not enough memory and enough space can be freed in the new generation, the new object is placed directly.
  2. if there is not enough memory to hold new objects, the new generation of objects will be promoted to the old generation. Make room for a new object

that's the problem. To sum up, if f.next = null is not set. Delete the header element twice in a row without triggering the Safepoint. There will be a reference relationship between F1 and f2.
when a new object needs to be created and the new generation is out of memory. F2 will be promoted to the older generation rather than immediately recycled.

add:

    Not setting
  1. to null does not cause memory leaks.
  2. optimizes GC in so much detail that current GC implementations should be considered. Citing the original JDK1.4, source code used in the original text has no significant difference in the case of JDK12 and sufficient memory
< hr >

specialize in the three parties, if there are any mistakes, I hope you can correct them


f is not necessarily unreachable
for example, ListItr may hold a reference to f
without this line

f.next = null; // help GC

it is possible that when LinkedList no longer needs GC, because other objects hold ListItr,ListItr and hold f ,
and f . Next points to other nodes, so that the nodes in the LinkedList will not be leaked by GC, memory.

this is my understanding. Please correct anything that is wrong.

supplement it with code

// 
LinkedList<?> list = new LinkedList(); 

//  iteratorlistfirst Node
ListIterator<?> iterator = list.listIterator(0); 

list.removeFirst();
list = null; // listlistGCfirstiterator

//  f.next = null; // help GCGCfirstnextiteratorfirst
// listNodeiteraterGCGCiterator
Menu