This is the 22nd day of my participation in the August More Text Challenge

This paper continues the previous article | the JVM garbage collection strategy (3), finally summarized.

Four, to sum up

We analyzed garbage collection policy, garbage collection locations, and reference types in three sections, so what should we pay attention to in actual production code? The JVM uses reachable algorithms to help you recycle garbage automatically, but it is important to note that even if an object is unreachable, it will not necessarily be recycled. The complete garbage collection process is as follows.

Analysis from the graph:

  • Check whether the object has a reference chain to GC Roots. If there is a reference chain, the object will not be recycled. If there is a reference chain, the object will be sentenced to death with a reprieve.
  • So how do you sentence this person to death, and that depends on whether the person is necessary to execute the person#finalizeMethods. ifThere is no need toThe first is that the object is not overwritten#finalizeMethod, or a second JVM has already called#finalizeMethod), then directly recycle. ifIt is necessary toRecycle, that puts this object inF-QueueThe JVM then automatically creates a thread with a lower priorityfinalizerTo execute the object#finalizeMethods.
  • If you re-establish a connection path for this object to any of the objects in the root object, the object will be converted fromF-Queue, and then do not perform the collection. The object is reachable to the root object again.

We analyzed it with a piece of code.

public class GCProcess { private static GCProcess gcBean; @SneakyThrows public static void main(String[] args) { gcBean = new GCProcess(); gcBean = null; System.gc(); #0 TimeUnit.SECONDS.sleep(1); if (gcBean == null) { System.out.println("gcBean == null"); } else { System.out.println("gcBean is available"); } TimeUnit.SECONDS.sleep(1); gcBean = null; #2 System.gc(); #3 if (gcBean == null) { System.out.println("gcBean == null"); } else { System.out.println("gcBean is available"); } } @Override protected void finalize() { System.out.println("#finalize in..." ); gcBean = this; }}Copy the code

We define an object, GCProcess, which overrides the Finalize method. The result is as follows:

Then we comment out line #2

//gcBean = null; # 2Copy the code

The result is as follows:

The principle is very simple, execute line #1, execute finalize method for the first time, there is an operation in the method, and re-establish the connection between the object and the object, so the object is not recycled. It then executes to line #2, eliminating the connection to the root object if commented, and not uncommented. Then when you go to line #3 for garbage collection, you get a different effect.

So we’re going to:

  • Avoid usingfinalizeMethods, improper operation may lead to unintended problems;
  • If you have to do something at the end of the program, what do you recommendtry... catch... finally;
  • The second is that it is recommended to assign a reference variable to an object that does not applynull.