Because love so insist, because love so wait. Through the long days without drama to play, finally for the spring of life, mutual encouragement!!

1. The System. The understanding of gc ()

By default, Full gc is explicitly triggered by a call to system.gc () or runtime.getruntime ().gc().

However, system.gc () calls come with a disclaimer, and there is no guarantee that the call to the garbage collector will trigger gc immediately. [There is no guarantee that garbage collection will occur, just a hint to the JVM]

JVM implementers can use system.gc() calls to determine the JVM’s GC behavior. 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.

System.runfinalization (); The console is not guaranteed to print, proving that system.gc () is not guaranteed to execute gc

public class SystemGCTest { public static void main(String[] args) { new SystemGCTest(); System.gc(); // Remind JVM garbage collector to perform GC, but not sure whether to perform GC immediately // with Runtime.getruntime ().gc(); Have the same effect. System.runFinalization(); } @override protected void Finalize () throws Throwable {super.finalize(); System.out.println("SystemGCTest overwrites Finalize ()"); }}Copy the code

⑤. Manual GC understands the collection behavior of unreachable objects

public class LocalVarGC { public void localvarGC1() { byte[] buffer = new byte[10 * 1024 * 1024]; //10MB System.gc(); //[GC (system.gc ())] [PSYoungGen: 14174K->10736K(76288K)] 14174K->10788K(251392K), 0.0089741 secs] [Times: User =0.01 sys=0.00, real=0.01 secs] //[Full GC (system.gc ()) [PSYoungGen: 10736K->0K(76288K)] [ParOldGen: [Times: 3253K->3253K], [Metaspace: 3253K->3253K], 0.0074098secs] [Times: 3253K->3253K] User =0.01 sys=0.02, real=0.01 secs]} public void localvarGC2() {byte[] buffer = new byte[10 * 1024 * 1024]; buffer = null; System.gc(); //[GC (system.gc ())] [PSYoungGen: 14174K->544K(76288K)] 14174K->552K(251392K), 0.0011742 secs] [Times: User =0.00 sys=0.00, real=0.00 secs] //[Full GC (system.gc ()) [PSYoungGen: 544K->0K(76288K)] [ParOldGen: 8K->410K(175104K)] 552K->410K(251392K), [Metaspace: 3277K->3277K(1056768K)], 0.0054702 secs] [Times: User =0.01 sys=0.00, real=0.01 secs]} public void localvarGC3() {{byte[] buffer = new byte[10 * 1024 * 1024]; } System.gc(); //[GC (system.gc ())] [PSYoungGen: 14174K->10736K(76288K)] 14174K->10784K(251392K), 0.0076032 secs] [Times: User =0.02 sys=0.00, real=0.01 secs] //[Full GC (system.gc ()) [PSYoungGen: 10736K->0K(76288K)] [ParOldGen: [Times: 3252K->3252K], [Metaspace: 3252K->3252K(1056768K)], 0.0096328secs] [Times: 3252K->3252K(1056768K)] User =0.01 sys=0.01, real=0.01 secs]} public void localvarGC4() {{byte[] buffer = new byte[10 * 1024 * 1024]; } int value = 10; System.gc(); //[GC (system.gc ())] [PSYoungGen: 14174K->496K] 14174K->504K(251392K), 0.0016517 secs] [Times: User =0.01 sys=0.00, real=0.00 secs] //[Full GC (system.gc ()) [PSYoungGen: 496K->0K(76288K)] [ParOldGen: 8K->410K(175104K)] 504K->410K(251392K), [Metaspace: 3279K->3279K(1056768K)], 0.0055183secs] [Times: } public void localvarGC5() {localvarGC1(); System.gc(); //[GC (system.gc ())] [PSYoungGen: 14174K->10720K(76288K)] 14174K->10744K(251392K), 0.0121568secs] [Times: User =0.02 sys=0.00, real=0.02 secs] //[Full GC (system.gc ()) [PSYoungGen: 10720K->0K(76288K)] [ParOldGen: 24K-> 24K (175104K)] 24744K -> 24650k (251392K), [Metaspace: 3279K->3279K(1056768K)], 0.0101068secs] [Times: User =0.01 sys=0.02, real=0.01 secs] //[GC (system.gc ())] [PSYoungGen: 0K->0K [Times: 0K->0K] 1050K -> 1050k [Times: 1050k] 1050k -> 1050k [Times: 1050k] 1050k -> 1050k [Times: 1050k] Sys =0.00, real=0.00 secs] //[Full GC (system.gc ()) [PSYoungGen: 0K->0K(76288K)] [ParOldGen: 10650K->410K(175104K)] 10650K->410K(251392K), [Metaspace: 3279K->3279K(1056768K)], 0.0045963 secs] [Times: Sys =0.00, real=0.00 secs]} public static void main(String[] args) {LocalVarGC local = new LocalVarGC(); local.localvarGC5(); }}Copy the code

2. Out of Memory

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

(2) The heap memory of the Java VM is insufficient. There are two reasons

  • The Java virtual machine has insufficient heap memory Settings (e.g., possible memory leaks; 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 with parameters Xms, Xmx.)
  • 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)

③ The implication is that the garbage collector will normally be triggered to clean up as much space as possible before an 0utOfMemoryError 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. In Java nio. BIts. ReserveMemory () method, we can clearly see the System. The gc () is called, to clean up space.

(4) Of course, the garbage collector will not be triggered in every case (for example, if we allocate a large object, such as a large array that exceeds the maximum size of the heap, the JVM can determine that garbage collection does not solve the problem, so it simply throws an OutOfMemoryError).

3. 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 and even OOM, which can also be called a “memory leak” in the broad sense

③ Although a memory leak does not immediately cause the program to crash, once a memory leak occurs, the available memory in the program will be gradually nipped until all the memory is exhausted, and finally the 0utOfMemory exception occurs, causing the program to crash.

(4) 8 cases of Memory leakage in Java

  1. Singleton pattern (The lifetime of a singleton is the same as that of an application, so if a singleton holds a reference to an external object, that object cannot be recycled, resulting in a memory leak.)

  2. Some resources that provide a close are not closed, causing a memory leak database connection (datasourse.getConnection ()), socket, and IO connections must be closed manually or they cannot be reclaimed.

  3. Static collection classes (such as HashMap, LinkedList, and so on. If these containers are static, their lifetime is consistent with that of a JVM program, and objects in the container cannot be released until the program ends, resulting in a memory leak. Simply put, a long-life object holds a reference to a short-life object, which cannot be reclaimed because the long-life object holds a reference to it, even though the short-life object is no longer in use.)

  4. The inner class holds the outer class (the inner class holds the outer class if a method of an instance object of the outer class returns an instance object of the inner class. The inner class object is referenced for a long time, and even though the outer class instance object is no longer used,** since the inner class holds the instance object of the outer class, the outer class object will not be garbage collected,** this will also cause a memory leak.

  5. Unreasonable scope of variables (Generally speaking, a variable is defined in a larger scope than it can be used, which is likely to cause memory leaks. On the other hand, if the object is not set to NULL in a timely manner, memory leaks can occur.)

  6. Change the hash

  7. Cache leaks (Another common source of memory leaks is caches, which are easy to forget once you put object references into the cache. For example, when the project went live, the application started very slowly until it died because the code would load data from a table into the cache (memory). The test environment only had hundreds of data, but the production environment had millions of data.

  8. Listeners and callbacks (Another common source of memory leaks is listeners and other callbacks, which can accumulate if clients register callbacks in the API you implement without explicitly canceling them)

    Public class MemoryLeak {static List List = new ArrayList();

    public void oomTests() { Object obj = new Object(); // Local variable list.add(obj); }Copy the code

    } public class UsingRandom {private String MSG; public void receiveMsg(){ //private String msg; readFromNet(); // Accept data from the network and save to MSG saveDB(); // add MSG to database // MSG = null; Public class ChangeHashCode {public static void main(String[] args) {HashSet set = new HashSet(); Person p1 = new Person(1001, “AA”); Person p2 = new Person(1002, “BB”);

    set.add(p1); set.add(p2); p1.name = "CC"; set.remove(p1); System.out.println(set); //2 objects!Copy the code

    // set.add(new Person(1001, “CC”)); // System.out.println(set); // set.add(new Person(1001, “AA”)); // System.out.println(set);

    }
    Copy the code

    }

4.Stop The World

Stop a the World, STW, refers to the application stopping during a Gc event. A pause occurs when the entire application thread is suspended without any response, a bit like being stuck. This pause is called STW

The STW event does not matter which GC is used, all GC has this event.

③ Even G1 can’t completely avoid Stop the World, but garbage collectors are getting better and more efficient, reducing pause times as much as possible.

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

⑤ Do not use system.gc () in development, it will cause full GC, which will cause Stop the world

⑥ What can cause stop the world

  • Enumerating root nodes (GC Roots) in the reachability analysis algorithm cause all Java execution threads to pause
  • STW phenomenon occurs during GC (user thread will be suspended when finalize() method is called
  • System. The gc () | calls to finalize () method

5. Parallelism and concurrency in multithreading

Concurrent in an operating system, a Concurrent operation refers to a period of time when several programs are running between their start and completion, and they are all 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, make full use of the CPU performance diagram:

When the system has more than one CPU, while one CPU is running a process, the other CPU can run another process. The two processes do not occupy CPU resources but can run simultaneously, which is called Parallel. In fact, parallelism is not determined by the number of cpus, but the number of CPU cores.

6. Parallel, serial and concurrent garbage collection

①. Parallel: Refers to multiple garbage collection threads working in Parallel while the user thread is still in the waiting state. Be the ParNew, Parallel Avenge, Parallel 0ld;

Serial (Serial) (2).

In contrast to the concept of parallelism, a single thread executes. If memory is insufficient, the program is paused and the JVM garbage collector is started for garbage collection. Recycle, and then start the program thread. Illustration:

(3) concurrently.

The user thread and the garbage collector thread execute simultaneously (but not necessarily in parallel, but alternately). The garbage collector thread does not pause while executing the user program.

7. Safepoint

The program does not always pause to start GC, but only at certain 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 longer to execute as Safe points, such as method calls, loop jumps, and exception jumps.

③ How do you check that all threads run to the nearest safe point when GC occurs?

  • Preemptive interrupt: (no virtual machine currently uses it) interrupts all threads first. If there are still threads that are not at the safe point, restore the thread and let it run to the safe point.
  • Active Interrupts: Sets an interrupt flag, which threads actively poll when running to Safe Point, and suspends themselves if the interrupt flag is true.

8. Safe Region

①. Safepoint mechanism ensures that during program execution, a Safepoint that can enter GC will be encountered within a short period of time. 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 fragment in which the reference relationships of objects do not change and it is safe to start GC anywhere. We can also think of Safe Region as Safepoint extended.

③. Actual implementation:

  • When a thread runs into Safe Region code, it first identifies that it has entered the Safe Region. If GC is issued during that time, the JVM ignores the thread identified as being in the Safe Region state.
  • When the thread is about to leave the SafeRegion, 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 SafeRegion;

9. Reference

(1) We wish to describe a class of 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 scenarios?

After JDK 1.2,Java has expanded the concept of Reference, including Strong Reference, Soft Reference, Weak Reference and Phantom The intensity of these four kinds of references gradually decreases in turn

3. 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 subclass of Reference, only the finalizer Reference is visible within the package, and the other three Reference types are public and can be directly used in the application

⑤. A brief introduction to strong and weak virtual references

  • StrongReference: The most traditional definition of a reference is a reference assignment that is common in program code, such as 0bject 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: Objects are collected 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: an object associated with a WeakReference 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. Find and recycle
  • Virtual reference: The existence of a virtual reference does not affect the lifetime of an object and cannot be used to obtain an instance of an object. The only purpose of setting a virtual reference association for an object is to receive a system notification when the object is reclaimed by the collector (reclaim trace)

1. Strong references: No collection

  • 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 that has no other reference relationship can be garbage collected as long as it exceeds the scope of the reference or explicitly sets the corresponding (strong) reference to NULL, 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.

2. Soft reference: If the memory is insufficient, 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. Note: A collection is a collection of objects that are not referenced in a strong reference

Soft references are usually used to implement memory sensitive caches. 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

Similar to weak references, but the Java virtual machine tries to keep soft references alive as long as possible. Have to clean up

④.

  1. When memory is sufficient: soft-referenced reachable objects are not reclaimed
  2. When memory runs out: Reachable soft-referenced objects are reclaimed

(5). The JDK is 1. 2 after edition provides a Java. Lang. Ref. SoftReference class to achieve soft references.

Object obj = new Object (); // declare a strong reference to SoftReference<0bject> sf = new SoftReference<0bject>(obj); // install soft reference obj = null; // Destroy strong referencesCopy the code

⑥. Test the code

-xms10m -xmx10m -xx :+PrintGCDetails */ public class SoftReferenceTest {public static class User { public User(int id, String name) { this.id = id; this.name = name; } public int id; public String name; @Override public String toString() { return "[id=" + id + ", name=" + name + "] "; }} public static void main(String[] args) {// create an object and establish a SoftReference // SoftReference<User> userSoftRef = new SoftReference<User>(new User(1, "songhk")); // This is equivalent to the following three lines User u1 = new User(1,"songhk"); SoftReference<User> userSoftRef = new SoftReference<User>(u1); u1 = null; // Remove strong references // Retrieve strong references from soft references system.out.println (usersoftref.get ()); System.gc(); System.out.println("After GC:"); // // gets the object in the soft reference system.out.println (usersoftref.get ()) after garbage collection; // Reachable objects that do not recycle soft references due to sufficient heap space memory. Byte [] b = new byte[1024 * 1024 * 7]; byte[] b = new byte[1024 * 1024 * 7]; byte[] b = new byte[1024 * 7168 - 399 * 1024]; } catch (e) {e.printstackTrace (); System.out.println(usersoftref.get ())); system.out.println (usersoftref.get ()); // The garbage collector will reclaim soft-referenced reachable objects before reporting OOM. }}}Copy the code

3. Weak references: Find and recycle

Weak references are also used to describe non-essential objects. Objects associated with weak references will only 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, it is not always possible to find objects holding weak references quickly. In this case, weak reference objects can exist for a long time.

Weak references and soft references, when constructing weak references, you can also specify a reference queue. When weak references are reclaimed, they will be added to the specified reference queue. By this queue, you can track the status of the reclaimed objects.

(4) Soft and weak references are good for storing unnecessary cached data. 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

5. After JDK1.2 version of a Java 2 Tim. Lang. Ref. The WeakReference class to implement a weak reference

Object obj = new Object (); // declare strong reference WeakReference<0bject> sf = new WeakReference<0bject>(obj); Obj = null; // Destroy strong referencesCopy the code

Have you used WeakHashMap in your development?

  1. By looking at WeakHashMap source code, you can see that its internal class Entry uses weak references

  2. Line 702 -> private static class Entry<K,V> extends WeakReference implements Map.Entry<K,V> {… line 702 -> private static class Entry<K,V> extends WeakReference implements Map. }

    public class WeakReferenceTest { public static class User { public User(int id, String name) { this.id = id; this.name = name; }

    public int id; public String name; @Override public String toString() { return "[id=" + id + ", name=" + name + "] "; WeakReference<User> userWeakRef = new WeakReference<User>(new) WeakReference<User>(new) User(1, "songhk")); // Retrieve the object system.out.println (userWeakref.get ()); System.gc(); System.out.println("After GC:"); system.out.println ("After GC:"); // Try again to get the object system.out.println (userWeakref.get ()) from the weak reference; }}Copy the code

4. Virtual reference: Object reclamation trace

Phantom Reference, also known as “Phantom Reference” or “Phantom Reference”, is the weakest of all Reference types.

②. 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. The get method of a virtual reference always returns null, so the corresponding reference object cannot be accessed

(4) Since virtual references can track the collection time of objects, it is also possible to place some resource release operations in virtual references.

The PhantomReference class was provided after JDK 1.2 to implement virtual references.

object obj = new object();
ReferenceQueuephantomQueue = new ReferenceQueue( ) ;
PhantomReference<object> pf = new PhantomReference<object>(obj, phantomQueue); 
obj = null;
Copy the code

⑥. Test the code

/*** * -xms10m -xmx10m */ public class MyObject { public static void main(String[] args) { ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue(); PhantomReference<MyObject> phantomReference = new PhantomReference<>(new MyObject(),referenceQueue); //System.out.println(phantomReference.get()); List<byte[]> list = new ArrayList<>(); new Thread(() -> { while (true) { list.add(new byte[1 * 1024 * 1024]); try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(phantomReference.get()); } },"t1").start(); new Thread(() -> { while (true) { Reference<? extends MyObject> reference = referenceQueue.poll(); if (reference ! Println = system.out.println ("*********** virtual object added to the queue "+reference); } } },"t2").start(); // Pause the thread for a few SECONDS try {timeunit.seconds.sleep (5); } catch (InterruptedException e) { e.printStackTrace(); Override protected void finalize() throws Throwable {// GC Finalize method over System.out.println("gc finalize method over"); }}Copy the code

The next article, garbage Collection 12, part 03 – A detailed explanation of common garbage collectors

Reference video: Silicon Valley JVM complete tutorial, millions of playback, the peak of the network (Song Hongkang details Java VIRTUAL machine) reference books: in-depth understanding of the Java virtual machine