How do I determine whether an object should be reclaimed?

The heap holds almost all object instances in the Java world, and the first thing the garbage collector needs to do before collecting the heap is to determine which of these objects should be recycled.

Reference counting algorithm

Adds a reference counter to the object, incrementing its value by one each time it is referenced somewhere; When a reference is invalid, the counter value is reduced by one; An object whose counter is zero at any point in time cannot be used again.

The problem: It is difficult to solve the problem of circular references between objects.

None of the mainstream Java virtual machines use this method to manage memory.

Accessibility analysis algorithm

Basic idea: A series of root objects called “GC Roots” are used as the starting node set. From these nodes, search down according to the reference relationship, and the path that the search takes is called “reference chain”. If there is no reference chain connected between an object and GC Roots, Or in graph theory terms, when the object is unreachable from GC Roots, then the object cannot be used again. The following figure

Accessibility analysis algorithm

Image source: Understanding the Java Virtual Machine

Fixed objects that can be used as GC Roots include the following:

  • 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.
  • An object referenced by a constant in a method area, such as a reference in a string constant pool.
  • Objects referenced by 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.

Java four reference types

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

Java reference types

The finalize () method

If an object is found to have no reference chain connected to GC Roots after reachability analysis, it will be marked for the first time and then filtered by whether it is necessary to execute the 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”.

Objects can escape garbage collection by re-associating themselves with objects on the reference chain in the Finalize () method.

PS: I haven’t written about this method yet. Not recommended.

/ * ** This code demonstrates two things:* 1. Objects can save themselves when GC is performed.* 2. There is only one chance to save, because the finalize() method of an object will be called automatically by the system at most once * * Code source: Understanding the Java Virtual Machine * @author : fuyuaaa  * @dateTherefore: 2020-06-03* / public class FinalizeEscapeGC {  public static FinalizeEscapeGC SAVE_HOOK = null;   public void isAlive(a) {  System.out.println("yes, i am still alive :)");  }   @Override  protected void finalize(a) throws Throwable {  super.finalize();  System.out.println("finalize method executed!");  FinalizeEscapeGC.SAVE_HOOK = this;  }   public static void main(String[] args) throws Throwable {  SAVE_HOOK = new FinalizeEscapeGC();  // The object successfully saves itself for the first time  SAVE_HOOK = null;  System.gc();  // Because the Finalizer method has a low priority, pause for 0.5 seconds to wait for it  Thread.sleep(500);  if(SAVE_HOOK ! =null) {  SAVE_HOOK.isAlive();  } else {  System.out.println("no, i am dead :(");  }    // The following code is exactly the same as above, but the save fails because Finalize will only be executed once  SAVE_HOOK = null;  System.gc();  // Because the Finalizer method has a low priority, pause for 0.5 seconds to wait for it  Thread.sleep(500);  if(SAVE_HOOK ! =null) {  SAVE_HOOK.isAlive();  } else {  System.out.println("no, i am dead :(");  }  } }  result: finalize method executed! yes, i am still alive :) no, i am dead :( Copy the code

Method area garbage collection

There are two main parts of garbage collection in method area:

Obsolete constants: There is no place to reference this constant

Type no longer in use :(meets all three criteria)

  • 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 been reclaimed.
  • 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.

Garbage collection algorithm

Mark-clear algorithm

First, mark all the objects that need to be recycled. After the mark is completed, all the marked objects are recycled. Alternatively, you can mark surviving objects and uniformly reclaim all unmarked objects.

Disadvantages:

  • The execution efficiency is not stable. The execution efficiency of both marking and clearing processes decreases with the increase of the number of objects.
  • Fragmentation of memory space can cause large objects to fail to allocate memory and have to be gc early.

Mark-copy algorithm

Divide the available memory into two equally sized pieces by capacity and use only one piece at a time. When this area of memory is used up, the surviving objects are copied to the other area, and the used memory space is cleaned up again.

Disadvantages:

  • There will be a lot of overhead for inter-memory replication
  • Waste half the space

Most of today’s commercial Java virtual machines use this collection algorithm in preference to recycle the new generation.

Mark-collation algorithm

The marking process is still the same as the mark-clean algorithm, but instead of cleaning up the recyclable objects directly, the next step is to move all surviving objects to one end of the memory space, and then clean up the memory directly beyond the boundary.

Disadvantages:

  • If there are a large number of live objects, moving live objects and updating all references to them can be a very heavy operation, and such object movement must be suspended for the entire user application.

Classic garbage collector

The HotSpot VIRTUAL machine garbage collector

PS:

  • The image above shows the HotSpot VIRTUAL machine. It can be used with a line.

  • Due to maintenance and compatibility testing costs, the Serial+CMS and ParNew+Serial Old combinations were declared obsolete in JDK 8 (JEP 173) and were completely removed from support in JDK 9 (JEP 214).

  • Parallel: Parallel describes the relationship between multiple garbage collector threads, indicating that more than one such thread is working together at the same time. By default, the user thread is in a waiting state.

  • Concurrent: Concurrency describes the relationship between garbage collector and user threads, indicating that both garbage collector and user threads are running at the same time. Since the user thread is not frozen, the program can still respond to service requests, but the throughput of the application’s processing is affected because the garbage collector thread occupies a portion of the system resources.

Serial collector

  • The most basic and the oldest
  • Cenozoic collector
  • Single thread
  • Mark-copy algorithm
  • Will cause “Stop The World”
Serial:Serial Old collector running schematic

ParNew collector

  • The multithreaded parallel version of the Serial garbage collector
  • Cenozoic collector
  • Multithreading parallelism
  • Mark-copy algorithm
  • Will cause “Stop The World”
ParNew:SerialOld collector running schematic

Parallel avenge

  • Cenozoic collector
  • Multithreading parallelism
  • Mark-copy algorithm
  • Will cause “Stop The World”
  • The collector’s goal is to achieve a manageable throughput
    • Control the maximum garbage collection pause time -XX: MaxGCPauseMillis
    • Directly set the throughput size -xx: GCTimeRatio
    • -xx: +UseAdaptiveSizePolicy

Serial Old garbage collector

  • An older version of the Serial collector
  • Single thread
  • Mark-collation algorithm
  • Will cause “Stop The World”
Serial:SerialOld Collector runs schematic 2

Paraller Old Garbage collector

  • An older version of the Parallel Exploiter
  • Multithreaded concurrency
  • Mark-collation algorithm
  • Began in JDK6 has
The ConcurrentMarkSweep collector is shown in action

CMS collector

  • Mark-clear algorithm
  • Aim to obtain the shortest collection pause time
The ConcurrentMarkSweep collector is shown in action

Specific steps:

  • Advantages:
    • Concurrent collection, low pause
  • Disadvantages:
    • It is sensitive to processor resources and can tie up threads during the concurrent phase, resulting in low overall throughput.
    • Unable to handle “floating garbage” (new garbage generated during the concurrent phase).
    • The Serial Old collector is temporarily used to “Stop The World” for The Old collection.
    • Mark – clear, unable to handle space fragmentation (CMS default enabled memory fragmentation consolidation process).

Garbage First

G1 divides the contiguous Java heap into independent regions (regions) of equal size, each of which can act as the Eden space of the new generation, Survivor space, or old chronspace. The collector can apply different policies to regions that play different roles.

Regions also have a special class of Humongous regions that are used to store large objects. G1 considers large objects as long as the size of a Region exceeds half of its capacity.

Predictable pause time model: Using regions as the smallest unit of a single collection, the G1 collector tracks the “value” of garbage accumulation in each Region. The value is the amount of space acquired by the collection and the experience value of the collection time. It then maintains a priority list in the background. Regions that benefit the most from recycling value are prioritized, hence the name “Garbage First”.

Diagram of G1 collector running

Specific steps:

PS:

  • TAMS: When the collection thread is running at the same time as the user thread, there must be allocation of new objects. G1 sets two Pointers named Top at Mark Start (TAMS) for each Region to divide part of the Region space for the allocation of new objects in concurrent reclamation. The addresses of newly allocated objects must be above these two Pointers.
  • STAB: Primitive snapshot algorithm for handling the problem of objects disappearing when concurrency occurs. Take a look at this: links
  • Similar to CMS, The G1 collector is forced to freeze user thread execution if The speed of memory collection cannot keep up with The speed of memory allocation, resulting in a long “Stop The World” for Full GC (multi-threading).

Memory allocation and reclamation policies

  • Objects are allocated in Eden first. When Eden does not have enough space to allocate, a Minor GC is performed

    • In Minor GC, if the object cannot be placed into Survivor, it goes straight to the old age (allocation guarantee mechanism)
  • Large objects go straight to the old age, avoiding a lot of memory copying.

    • The HotSpot VIRTUAL machine provides the -xx: PretenureSizeThreshold parameter, which specifies that objects larger than this value are assigned directly to the older generation. The default value is 0, which means that any object (if larger than Eden, then older) will now be allocated by Eden.
  • Long-lived objects enter the old age, each object has an age counter, the object is born in Eden, and if it survives after the first Minor GC and can be placed in Survivor, the object is moved to Survivor and its object age is set to 1. Each time an object survives a Minor GC in a Survivor zone, its age increases by one year, and when it reaches a certain age (15 by default, with the -xx :MaxTenuringThreshold setting), it is promoted to the old age.

  • Dynamic object age determination: If the total size of all objects of the same age in Survivor space is greater than half of that in Survivor space, objects older than or equal to this age can enter the old age directly without waiting until -xx :MaxTenuringThreshold requires the age.

  • Before a Minor GC occurs, the virtual machine must check whether the maximum available contiguous space of the old generation is greater than the total space of all objects of the new generation. If so, the Minor GC can be guaranteed to be safe. If less than, the virtual opportunity to view the first – XX: HandlePromotionFailure parameter setting values are allowed to guarantee fail; If allowed, it continues to check whether the maximum available contiguous space of the old age is greater than the average size of the objects promoted to the old age, and if so, a Minor GC is attempted, although this Minor GC is risky; If less than, or – XX: HandlePromotionFailure Settings do not allow the risk, it would then to conduct a Full GC. If the guarantee still fails (the object is suddenly larger than the previous average size), FullGC will continue.

    PS: – XX: HandlePromotionFailure in JDK6 has 24 after the Update is invalid.

reference

In-depth Understanding of the Java Virtual Machine

The images are from Inside Understanding the Java Virtual Machine and drawn by myself

This article is formatted using MDNICE