Hello, today for you children to share JVM, quickly take out a small notebook to write down!

Out of memory

Out Of Memory (OOM) refers to the Memory that cannot be reclaimed or too much Memory is used in an application system, so that the program uses more Memory than the maximum available Memory.

The official documentation explains the memory overflow by saying that there is no free memory, and the garbage collector cannot provide more memory.

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.

Causes of memory overflow:

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

A large number of large objects are created in the code and cannot be collected by the garbage collector for a long time.

OOM Exception information changes:

: before JDK7 and Java. Lang. OutOfMemoryError: PermGen space

JDK8:java.lang.OutofMemoryError:Metaspace

Before an OutOfMemoryError is thrown, the garbage collector is usually triggered to clean up as much space as it can. Of course, not every case will trigger the garbage collector; 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.

A memory leak

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.

Java uses a reachability analysis algorithm to flag garbage; the data at the top is unreachable and needs to be recycled.

Later, there are some objects that are not used, which should be disconnected, but there are some chains that are not broken, so there is no way to reclaim. This causes a memory leak.

Relationship between memory leakage and memory overflow

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.

For example,

Buy a house: 80 square meters of house, but there are 10 square meters of shared area, we can not use the 10 square meters of space, this is the so-called memory leak

Singleton pattern; The life cycle of a singleton is as long as that of an application, so if a singleton holds a reference to an external object that is no longer used, that external object cannot be reclaimed, resulting in a memory leak.

The resource providing close is not closed, causing a memory leak. Database connections, network connections, and IO connections must be manual or they cannot be reclaimed.

STW

Stop-the-world, or STW for short, refers to the application pauses that occur during garbage collection. A pause occurs when the entire application thread is suspended without any response, a bit like being stuck.

The STW event is independent of which GC is used, because all GC’s have this event. No garbage collector can completely avoid stop-the-world situations, except that garbage collectors are getting better and better at collecting efficiently, reducing pause times as much as possible.

Why STW for garbage collection?

During the garbage collection marking phase, the JVM uses a reachability analysis algorithm to mark objects as garbage, and if the object reference relationship changes during the analysis, the accuracy of the analysis results cannot be guaranteed.

So to STW garbage collection, the analysis must be done in a snapshot to ensure consistency.

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.

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.

System.gc

By default, FullGC is explicitly triggered by a call to Runtime.geTruntime ().gc() from system.gc (), which collects both old and new generations in an attempt to free up memory occupied by discarded objects.

The source code calls Runtime.getruntime ().gc();

Meaning:

Run the garbage collector.

Calling the GC method means that the Java virtual machine is trying to reclaim unused objects so that the memory they currently occupy can be reused quickly. When control is returned from method calls, the Java virtual machine has done its best to reclaim space from all discarded objects. Calling system.gc () is effectively equivalent to calling runtime.getruntime ().gc().

Call System. The gc (); Calls to the garbage collector are not guaranteed; In general, garbage collection should be automatic and not manually triggered.

The code demonstrates whether GC is triggered

// GC will almost always call Finalize () a few more times (15~30) when the thread is not busy.

public class MainTest {

public static void main(String[] args) { new MainTest(); // It is recommended that the garbage collector perform garbage collection behavior without immediately executing system.gc ();Copy the code

/ / call System. The gc (); System.runfinalization (); The Finalize () method is forced to be called when the reference object is lostCopy the code

// System.runFinalization();

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

}

Serial, parallel, and concurrent garbage collection

PS: parallel, concurrent, serial

  • Concurrent:

In operating systems, several programs running at a time, all running on the same processor.

Then the CPU polls the programs on these different threads through the time slice. Because the CPU processing speed is very fast, as long as the time interval is properly handled, the user feels that multiple applications are going on at the same time.

Concurrent tasks preempt each other’s resources.

  • In parallel:

When a CPU has more than one CPU core, when one CPU core executes a process, the other CPU core can execute the other process at the same time. The two processes do not occupy CPU 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.

  • Serial:

Only one CPU is allowed to execute programs at a time.

  • Parallel garbage collection: After the user thread is stopped, multiple GC threads are collecting garbage in parallel, while the user thread is still in a waiting state and STW occurs.

  • Concurrent garbage collection: When multiple garbage collection threads work at the same time, the GC thread and the user thread run at the same time without STW.

  • Serial garbage collection: Only one CPU is allowed to perform garbage collection operations at a time, and the collector freezes all application threads while it works, making it unusable in the server environment for all purposes and purposes.

Safe points and safe areas

safer

Program execution does not always pause to begin GC, but only at certain points, called safe points.

The choice of safe points is important because too few can lead to long GC waits, and too frequent can lead to 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 some instructions that take a long time to execute as safety points.

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

Preemptive interrupt: Interrupt 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. No virtual machines are currently used.

Active interrupts: Sets an interrupt flag, each thread polls this flag when it is safe to run, and suspends itself if the interrupt flag is true.

The safety area

The safe point mechanism ensures that the program execution will not take too long to reach a safe point that can enter the 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, safety zones are needed.

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.

Think of a safety point as an extended safety zone.

When a thread runs into code in a safe zone, it is first identified as having entered the safe zone, and if GC occurs during this time, the JVM ignores the thread identified as being in the safe zone state

When a thread is about to leave the safe zone, 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 zone;

reference

After JDK1.2, Java has expanded the concept of references into:

  • StrongReference: the most traditional definition of a reference. 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. An out-of-memory exception is thrown if there is not enough memory after this collection.

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

  • 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 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 intensity of these four citations gradually decreases in turn. Except for strong references, the other three references can be found in the java.lang.ref package.

The premise of reference garbage collection above is that the objects are all touchable, and if they are not, they are directly collected by the garbage collector.

Strong reference

In Java programs, the most common reference type is strong reference, which is the most common common 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.

Strong reference test

The object pointed to by a strong reference will not be reclaimed by the system at any time. The VM will throw an OOM exception and will not reclaim the object pointed to by a strong reference.

So strong references are a major cause of memory leaks.

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.

The first collection here refers to unreachable objects

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.

Soft reference testing

/ * *

  • Soft reference testing

  • Vm parameters:

  • -Xms10m

  • -Xmx10m

  • -XX:+PrintGCDetails

* /

public class MainTest {

public static void main(String[] args) { //SoftReference<User> softReference = new SoftReference<>(new User("hello")); // The above line of code is equivalent to the following three lines of code User User = new User("hello"); SoftReference<User> softReference = new SoftReference<User>(user); // The strong reference object must be destroyed otherwise there is no point in creating a soft reference object user = null; System.out.println(" before creating a large object: "+ softreference.get ()); Byte [] bytes = new byte[1024 * 1024 *7]; }catch (Throwable e) { e.printStackTrace(); }finally {system.out.println (" after creating a large object: "+ softreference.get ()); }}Copy the code

}

class User {

private String name;

public User(String name) {

    this.name = name;

}

@Override

public String toString() {

    return "User{" +

            "name='" + name + '\'' +

            '}';

}
Copy the code

}

A weak reference

Weak references are also used to describe non-essential objects that can 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.

Because garbage collector threads are usually of low priority, objects holding weak references are not necessarily 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.

Weak reference test

Phantom reference

Virtual references, also known as “ghost references” or “phantom references,” are 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.

Virtual reference test

/ * *

  • Virtual reference test

* /

public class MainTest {

Public static MainTest obj; Static ReferenceQueue<MainTest> phantomQueue = null; @Override protected void finalize() throws Throwable { super.finalize(); System.out.println(" Call the finalize method of the current class "); obj = this; } public static void main(String[] args) { Thread thread = new Thread(() -> { while(true) { if (phantomQueue ! = null) { PhantomReference<MainTest> objt = null; try { objt = (PhantomReference<MainTest>) phantomQueue.remove(); } catch (Exception e) { e.getStackTrace(); } if (objt ! = null) {system.out.println (" Trace garbage collection: PhantomReferenceTest instance was GC "); } } } }, "t1"); thread.setDaemon(true); thread.start(); phantomQueue = new ReferenceQueue<>(); obj = new MainTest(); // Create a virtual reference to the PhantomReferenceTest object <MainTest> PhantomReference = new PhantomReference<>(obj, phantomQueue); try { System.out.println(phantomReference.get()); // remove strong references obj = null; System.out.println(" first GC operation "); system.out.println (" first GC operation ") System.gc(); Thread.sleep(1000); If (obj == null) {system.out.println ("obj is null"); } else {system.out.println ("obj is not null"); } system.out.println (" second GC operation "); obj = null; System.gc(); Thread.sleep(1000); If (obj == null) {system.out.println ("obj is null"); } else {system.out.println ("obj is not null"); } } catch (Exception e) { e.printStackTrace(); } finally { } }Copy the code

}

Well, today’s article is here, I hope to help you confused screen!