The first thing the garbage collector does before collecting the heap is determine which of these objects are “alive” and which are “dead” (objects that can no longer be used in any way).

Reference counting algorithm

As the name implies, this is to add a reference counter to an object, incrementing it when a new reference is present and decaying it when a reference is dead. Objects that reference a counter value of 0 are no longer used.

Disadvantages: A lot of extra processing is required to work correctly, for example, reference counting alone is difficult to solve the problem of objects referring to each other in a loop.

Advantages: simple principle, judgment efficiency is very high.

Accessibility analysis algorithm

The memory management subsystems of the current mainstream commercial programming languages (Java, C#, and all the way back to the old Lisp mentioned above) use Reachability Analysis algorithms to determine whether objects are alive or not.

The basic idea of this algorithm is to use a series of root objects called “GC Roots” as the starting node set. From these nodes, search down according to the Reference relationship. The path through the search process is called “Reference Chain”. Or in graph theory terms, when the object is unreachable from GC Roots, then the object cannot be used again.

As shown in Figure 3-1, object 5, Object 6 and Object 7 are related to each other, but they are not reachable to GC Roots, so they will be judged as recyclable objects.

Figure 3-1 Using the reachability analysis algorithm to determine whether an object is recyclable

GCRoots object

  • Objects referenced in the virtual machine stack (the local variable table in the stack frame), such as parameters, local variables, temporary variables, etc. used in the method stack called by each thread.
  • An object referenced by a class static attribute in a method area, such as a Java class reference type static variable.
  • Objects that are constant references in the method area, such as references in the String Constant pool (String Table).
  • Objects referenced by JNI (commonly referred to as Native methods) in the Native method stack.
  • Internal references to the Java virtual machine, such as Class objects corresponding to basic data types, resident exception objects (NullPointExcepiton, OutOfMemoryError), and system Class loaders.
  • All objects held by the synchronized keyword.
  • Jmxbeans that reflect Java virtual machine internals, callbacks registered in JVMTI, local code caches, and so on.

In addition to the fixed GCRoots above, there are also “temporary” objects. When garbage collection is initiated for only one area of the Java heap (as is typical for new generation garbage collection), it must be considered that the memory area is an implementation detail of the virtual machine itself (no memory area is visible from the user’s perspective), and not isolated. Therefore, objects in a certain region are completely likely to be referenced by objects in other regions in the heap. At this time, objects in these associated regions need to be added into the GC Roots set to ensure the correctness of the reachability analysis.

Third, talk about quotation

Prior to JDK 1.2, a reference was traditionally defined in Java: a reference was a reference to a block of memory or an object if the value stored in the reference represented the starting address of another block of memory.

Java expanded the concept of references after JDK version 1.2, Strongly re-reference, Soft Reference, Weak Reference, and Phantom Reference are divided into four types of references. The strength of these four types of references decreases successively.

Strong reference

Strong reference is the most traditional definition of “reference”, which refers to the reference assignment that is common in program code, such as “Object obj=new Object()”. In any case, the garbage collector will never reclaim the referenced object as long as the strong reference relationship exists.

Soft references

Soft references are used to describe objects that are useful but not necessary. Only objects that are associated with soft references are listed in the recycle range for a second collection before an out-of-memory exception occurs. If there is not enough memory in the recycle range, an out-of-memory exception is thrown. After JDK 1.2, the SoftReference class was provided to implement soft references.

A weak reference

Weak references are also used to describe non-essential objects, but they are weaker than soft references, and objects associated with weak references only survive until the next garbage collection occurs. When the garbage collector starts working, objects associated only with weak references are reclaimed, regardless of whether there is currently enough memory. WeakReference classes were provided after JDK 1.2 to implement weak references.

Phantom reference

Virtual references, also known as “ghost references” or “phantom references,” are the weakest type of reference 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. The PhantomReference class was provided after JDK 1.2 to implement virtual references.

To be or not to be?

Even if an object is judged to be unreachable in the reachability analysis algorithm, it is not “necessary to die”. At this time, they are still in the “probation” stage temporarily. In order to truly declare an object dead, at least two marking processes are needed.

** First tag: after the reachability analysis, it is found that there is no reference chain connected to GC Roots. Then, it will be tagged for the first time, and then filtered. The filter condition is whether the object needs to execute finalize() method. If the object does not override the Finalize () method, or if the Finalize () method has already been called by the virtual machine, then the virtual machine considers both cases “unnecessary to execute”. ** If the object is deemed necessary to finalize(), then the object will be placed ina Queue named F-queue, and then finalize() will be executed by a low-priority Finalizer thread automatically set up by the virtual machine.

** Second mark: ** object reachability analysis found no reference chain connected to GC Roots.

5. Recycling method area

There are two main parts of the method area garbage collection: obsolete constants and no longer used types.

Recycle and discard constant

This is very similar to recycling objects in the Java heap. For an example of literal recycling in the constant pool, if “Java” once to enter a string constants in the pool, but the current system and without any value is a string object “Java”, in other words, there is no any string object references in the constant pool “Java” constants, and no other place in the virtual machine refer to the literal. If a memory collection occurs at this point, and the garbage collector determines that it is necessary, the “Java” constant will be cleaned out of the constant pool by the system. Symbolic references to other classes (interfaces), methods, and fields in the constant pool are similar.

Reclaim a type that is no longer used

  • All instances of the class are already recycled, that is, there are no instances of the class or any of its derived children in the Java heap.
  • The classloader that loaded the class has already been recycled, a condition that is usually difficult to achieve unless it is a carefully designed alternative classloader scenario, such as OSGi, JSP reloading, and so on.
  • The java.lang.Class object corresponding to this Class is not referenced anywhere, and the methods of this Class cannot be accessed anywhere through reflection.

The Java virtual machine (JVM) is allowed to recycle useless classes that meet the above three criteria, only “allowed”, not necessarily recycled as objects do when they are no longer referenced. The HotSpot virtual machine provides the -xnoclassGC parameter to control whether or not to reclaim the type. You can also use -verbose: class and -xx: + traceclass-loading, -xx: +TraceClassLoading to view class loading and unloading information, where -verbose: class and -xx: +TraceClassLoading can be used on VMS in the Product version, and -xx: The + traceclasssemantics parameter requires FastDebug VIRTUAL machine support. In scenarios where bytecode frameworks such as reflection, dynamic proxies, and CGLib are used extensively, JSPS are dynamically generated, and custom class loaders such as OSGi are frequently used, the Ability of the Java VIRTUAL machine to type unload is often required to ensure that the method area is not overloaded with memory.