Note source: Silicon Valley JVM complete tutorial, millions of playback, the peak of the entire network (Song Hongkang details Java virtual machine)

Update: gitee.com/vectorx/NOT…

Codechina.csdn.net/qq_35925558…

Github.com/uxiahnan/NO…

[TOC]

12. Concepts related to garbage collection

12.1.system.gc () understanding

By default, Full GC is explicitly triggered by a call to system.gc() or runtime.getruntime ().gc(), which collects both old and new generations in an attempt to free up memory occupied by discarded objects.

However, system.gc () calls come with a disclaimer that does not guarantee a call to the garbage collector. (Immediate effect cannot be guaranteed)

JVM implementers can determine the JVM’s GC behavior through system.gc () calls. In general, garbage collection should be automatic and not manually triggered, otherwise it would be too much trouble. In special cases, such as when we are writing a performance baseline, we can call System.gc() between runs.

public class SystemGCTest {
    public static void main(String[] args) {
        new SystemGCTest();
        System.gc();// The JVM's garbage collector is reminded to perform gc, but not sure if gc will be performed immediately
        / / and the Runtime. GetRuntime (). The gc (); Have the same effect as
        
        System.runFinalization();// Enforce the finalize() method of objects that use references
    }

    @Override
    protected void finalize(a) throws Throwable {
        super.finalize();
        System.out.println("SystemGCTest overrides Finalize ()"); }}Copy the code

12.2. Memory Overflow and memory leak

Memory Overflow (OOM)

Memory leaks, though easier to understand than memory leaks, are also one of the main causes of program crashes.

Since GC is constantly evolving, it is generally less likely to happen unless the application’s memory footprint is growing so fast that garbage collection can no longer keep pace with memory consumption.

In most cases, the GC will do garbage collection for all ages, but if it is too late, it will do an exclusive Full GC operation, which will reclaim a large amount of memory for the application to continue to use.

The javadoc interpretation of OutOfMemoryError is that there is no free memory, and the garbage collector cannot provide more memory.

First, there is no free memory: the Java virtual machine has insufficient heap memory. There are two reasons:

  1. The Heap memory setting of the Java virtual machine is insufficient.

    For example, there may be a memory leak; It is also possible that the heap size is not reasonable, for example if we are dealing with a significant amount of data but do not explicitly specify the JVM heap size or specify a low value. We can adjust it with the arguments -xms and -xmx.

  2. A lot of large objects are created in the code and cannot be collected by the garbage collector for a long time (there are references)

    With older Oracle JDKS, outofMemoryErrors were common as we continued to add new types, because the size of persistent generations was limited and the JVM was very passive about persistent garbage collection (e.g., constant pool collection, unloading no longer needed types). Especially when there is a lot of dynamic type generation at run time; Similar to intern string cache taking up too much space can also cause OOM problems. Corresponding exception information, will be marked and permanent generation related: “Java. Lang. OutOfMemoryError: PermGen space.”

    Method with the introduction of metadata area, area of memory is no longer so embarrassed, to change, so the corresponding ooM ooM, exception information then becomes: “Java. Lang. OutofMemoryError: Metaspace”. Directly out of memory also causes OOM.

The implication is that the garbage collector is usually triggered to clean up as much space as it can before an OutOfMemoryError is thrown.

  • For example, in reference mechanism analysis, it is involved that the JVM will attempt to reclaim objects pointed to by soft references, etc.
  • injava.nio.BIts.reserveMemory()In the method, we can clearly see,System.gc()Will be called to clear space.

Of course, the garbage collector is not triggered in every case

  • For example, if we allocate a very large object, like a very large array that exceeds the maximum size of the heap, the JVM can determine that garbage collection is not going to solve the problem, so it simply throws an OutOfMemoryError.

Memory Leak

Also known as “storage leakage”. Strictly speaking, a memory leak is when objects are no longer used by the program, but the GC cannot reclaim them.

In practice, however, many times poor practices (or omissions) can lead to long object lifetimes, or even to a “memory leak” in the broad sense.

Although a memory leak does not immediately cause a program to crash, once a memory leak occurs, the available memory in the program will be gradually eaten up until all memory is exhausted, and finally an OutOfMemory exception occurs, causing the program to crash.

Note that the storage is not physical memory, but the virtual memory size, which depends on the size of the disk swap.

For example,

  1. The singleton pattern

    The life of a singleton is as long as that of an application, so a singleton that holds a reference to an external object cannot be recycled, resulting in a memory leak.

  2. Some resources that provide close are not closed, causing memory leaks

    Database connections (datasourse.getConnection ()), sockets, and IO connections must be closed manually or they cannot be reclaimed.

12.3. Stop The World

Stop-the-world, or STW, refers to application pauses that occur during GC events. A pause occurs when the entire application thread is suspended without any response, a bit like being stuck. This pause is called STW.

Enumerating root nodes (GC Roots) in the reachability analysis algorithm cause all Java execution threads to pause.

  • The analysis must be done in a snapshot that ensures consistency
  • Consistency means that the entire execution system appears to be frozen at a point in time throughout the analysis
  • If the object reference relationship changes constantly during the analysis, the accuracy of the analysis result cannot be guaranteed

Application threads that are interrupted by STW will resume after GC, and frequent interruptions will make users feel like a movie tape caused by slow network speed, so we need to reduce STW occurrences.

The STW event is independent of which GC is used; all GC’s have this event.

Even the G1 can’t completely avoid stop-the-world situations, except that garbage collectors are getting better and more efficient at collecting, reducing pause times as much as possible.

STW is automatically initiated and completed by the JVM in the background. When the user is not visible, all the normal working threads of the user are stopped.

Not using system.gc () in development will result in stop-the-world.

12.4. Parallelism and concurrency of garbage collection

Concurrent

In an operating system, a period of time in which several programs are running on the same processor.

Concurrency is not a true sense of the “on” at the same time, just take a CPU time was divided into several segments of time (time interval), and then switch back and forth between the several time interval, due to the CPU speed is very fast, as long as the time interval handled well, can make the user feel is more than one application at the same time.

Parallel

When the system has more than one CPU, when one CPU executes a process, the other CPU can execute another process. The two processes do not occupy CPU resources and can be carried out simultaneously, which is called Parallel.

In fact, the factor that determines parallelism is not the number of cpus, but the number of CPU cores. For example, a CPU can have multiple cores in parallel.

Suitable for scientific calculation, background processing and other weak interactive scenes

Concurrency vs parallelism

  • Concurrency is when multiple things happen at the same time at the same time.

  • Parallelism means multiple things happening at the same time.

  • Concurrent tasks preempt each other’s resources.

  • Parallel tasks do not grab resources from each other.

  • Parallelism occurs only in the case of multiple cpus or one CPU with multiple cores.

  • Otherwise, everything that seems to happen at the same time is actually executed concurrently.

Concurrent and parallel garbage collection

Concurrency and parallelism, in the context of talking about the garbage collector, can be explained as follows:

Parallel

Refers to multiple garbage collection threads working in parallel while the user thread is still waiting. Be the ParNew, Parallel Avenge, Parallel Old;

Serial

In contrast to the concept of parallelism, a single thread executes. If there is not enough memory, the program is paused and the JM garbage collector is started for garbage collection. Recycle, and then start the program thread.

Concurrent

The user thread executes simultaneously (but not necessarily in parallel, but alternately) with the garbage collector thread without pausing the user program. The user program continues to run while the garbage collector thread runs on another CPU. For example, CMS and G1

12.5. Safety points and Areas

safer

Program execution does not always pause to begin GC, but only at specific points, called “safepoints.”

The choice of Safe Points is important because too little can lead to long GC waits, and too often can cause performance problems at runtime. The execution time of most instructions is very short, and is usually based on “characteristics that make the program run for a long time”. For example, select instructions that take a long time to execute as Safe points, such as method calls, loop jumps, and exception jumps.

How do you check that all threads stop at the nearest safe point when a GC occurs?

Preemptive interrupts :(currently no VMS are used)

  • First, interrupt all threads. If there are still threads that are not at the safe point, restore the thread and let it run to the safe point. \

Active interrupt

Set an interrupt flag that each thread actively polls when running to Safe Point and suspends itself if the interrupt flag is true. (Polling mechanism)

Safe Resion

The Safepoint mechanism ensures that when a program executes, it will not take too long to encounter a Safepoint ready for GC. But what about when the program “doesn’t execute”? For example, when a thread is in the state of Sleep or Blocked, unable to respond to interrupt requests from the JVM, the thread “walks” to a safe point to interrupt the suspension, and the JVM is less likely to wait for the thread to wake up. In this case, a Safe Region is required.

A safe zone is a code snippet where the reference relationship of the object does not change and it is safe to start Gc anywhere in the zone. We can also think of Safe Region as Safepoint extended.

Actual execution:

  1. When a thread runs into Safe Region code, it first identifies that it has entered Safe Relgion, and if GC occurs during that time, the JVM ignores the thread identified as Safe Region
  2. When a thread is about to leave the Safe Region, it checks to see if the JVM has completed GC, and if so, continues running, otherwise the thread must wait until it receives a signal that it is Safe to leave the Safe Region;

12.6. More on quotes: strong quotes

We want to describe objects that can remain in memory when there is enough space; If memory space is tight after garbage collection, these objects can be discarded.

What’s the difference between a strong quote, a soft quote, a weak quote and a false quote? What are the specific usage scenarios?

After JDK1.2, Java has expanded the concept of references into: The strength of Strong Reference, Soft Reference, Weak Reference and Phantom Reference gradually decreases.

Except for strong references, the other three references can be found in the java.lang.ref package. The figure below shows the classes that correspond to these three reference types, and developers can use them directly in their applications.

.

In the Reference subclass, only finalizer references are visible within the package. The other three Reference types are public and can be used directly in applications

  • StrongReferenceThe most traditional definition of “reference” is the reference assignment that is common in program code.Object obj = new Object()“This quote relationship. In any case, the garbage collector will never reclaim the referenced object as long as the strong reference relationship exists.
  • SoftReferenceThese objects are included in the collection scope for a second collection before the system is about to run out of memory. If there is not enough memory after this collection, an out-of-memory exception is thrown.
  • WeakReference: Objects associated with weak references can only survive until the next garbage collection. When the garbage collector works, objects associated with weak references are reclaimed regardless of whether there is enough memory.
  • Virtual Reference: The existence of a virtual reference does not affect the lifetime of an object, nor can it be used to obtain an instance of an object. 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.

Strong References — Do not recycle

In Java programs, the most common type of reference is strong reference (more than 99% of all strong references in normal systems), which is our most common plain object reference and the default reference type.

When you use the new operator in the Java language to create a new object and assign it to a variable, the variable becomes a strong reference to the object.

Strongly referenced objects are touchable, and the garbage collector will never reclaim the referenced objects.

An ordinary object with no other references can be garbage collected as long as it exceeds the scope of the reference or explicitly assigns the corresponding (strong) reference to NU11, depending on the garbage collection policy.

In contrast, soft-referenced, weak-referenced, and vreferenced objects are soft-touchable, weak-touchable, and vtouchable objects, which can all be reclaimed under certain conditions. So, strong references are one of the main causes of Java memory leaks.

Strong reference example

StringBuffer str = new StringBuffer("hello mogublog");
Copy the code

The local variable STR refers to the heap space where the StringBuffer instance resides, and STR is a strong reference to the StringBuffer instance if the instance can be manipulated by STR

Corresponding memory structure

At this point, if I run another assignment statement

StringBuffer str1 = str;
Copy the code

Corresponding memory structure

Both references in this example are strong references, which have the following characteristics:

  • Strong references allow direct access to the target object.
  • The object pointed to by a strong reference will not be reclaimed by the system at any time. The VM would rather throw an OOM exception than reclaim the object pointed to by a strong reference.
  • Strong references can lead to memory leaks.

12.8. More about quotes: soft quotes

Soft Reference – When memory runs out, it is reclaimed

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.

Soft references are often used to implement memory sensitive caching. For example, caching is useful for soft references. If you have free memory, you can keep the cache for a while and clean it up when you run out of memory. This ensures that you don’t run out of memory while using the cache.

When the garbage collector decides to reclaim soft reachable objects at some point, it cleans up soft references and optionally stores them in a Reference Queue.

Similar to weak references, except that the Java virtual machine tries to keep soft references alive as long as possible and cleans them up when necessary.

After JDK1.2 edition provides a Java. Lang. Ref. SoftReference class to achieve soft references

Object obj = new Object(); // Declare strong references
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; // Destroy strong references
Copy the code

12.9. More on citation: Weak citation

Weak Reference — Discover and reclaim

Weak references are also used to describe non-essential objects, and only objects associated with weak references will survive until the next garbage collection occurs. During system GC, whenever a weak reference is found, objects associated only with weak references are reclaimed, regardless of whether the system heap space is fully used.

However, because garbage collector threads are usually of low priority, objects holding weak references are not always found quickly. In this case, weak reference objects can exist for a long time.

Like soft references, when constructing weak references, you can specify a reference queue. When a weak reference object is reclaimed, it is added to the specified reference queue. By this queue, you can track the reclaim status of the object.

Both soft and weak references are great for storing cache data that is not essential. If you do this, when the system runs out of memory, the cached data will be reclaimed without running out of memory. When memory resources are sufficient, these cached data can exist for quite a long time, thus speeding up the system.

WeakReference classes were provided after JDK1.2 to implement weak references

Object obj = new Object(); // Declare strong references
WeakReference<Object> sf = new WeakReference<>(obj);
obj = null; // Destroy strong references
Copy the code

The big difference between a weak-referenced object and a soft-referenced object is that when the GC is collecting, the algorithm checks to see if the soft-referenced object is being collected, whereas for weak-referenced objects, the GC always collects. Weakly referenced objects are easier and faster to collect by GC.

Interview question: Have you used WeakHashMap in your development?

WeakHashMap is used to store picture information, which can be recycled in time when the memory is insufficient, avoiding OOM

12.X. More on references: Virtual references

Phantom Reference — Object reclamation trace

Also known as “ghost reference” or “phantom reference”, it is the weakest of all reference types.

The existence of virtual references to an object does not determine its life cycle at all. If an object holds only virtual references, it is almost as good as no references and can be collected by the garbage collector at any time.

It cannot be used alone, nor can a virtual reference be used to get the referenced object. Always null when trying to get an object through the get() method of a virtual reference

The sole purpose of setting a virtual reference association for an object is to track the garbage collection process. For example, you can receive a system notification when the object is reclaimed by the collector.

Virtual references must be used with reference queues. A virtual reference must be created with a reference queue as an argument. When the garbage collector is about to reclaim an object and finds that it has a virtual reference, it adds the virtual reference to the reference queue after the object is reclaimed to inform the application of the object’s recycling status.

Because a virtual reference can track the reclaim time of an object, it is also possible to place some resource release operations in a virtual reference for execution and recording.

PhantomReference classes were provided after JDK1.2 to implement virtual references.

Object obj = new Object(); // Declare strong references
ReferenceQueue phantomQueue = new ReferenceQueue();
PhantomReference<Object> sf = new PhantomReference<>(obj, phantomQueue);
obj = null; 
Copy the code

12.11. Finalizer references

It is used to implement an object’s Finalize () method, which can also be called a finalizer reference. No manual encoding is required, and it is used internally with reference queues.

During GC, finalizer references are enqueued. The Finalizer thread finds the referenced object through the Finalizer reference and invokes its Finalize () method. The referenced object is reclaimed on the second GC