GC mechanism of jvm and four reference categories

     First, let's talk about the gc mechanism. Many people are asked about the gc mechanism of jvm in the interview, and they will naturally answer the reference counting method. In some of our common virtual machines, such as the python virtual machine, the reference counting method is used to mark garbage objects, but in the mainstream jvm, another mechanism is used, reachability analysis. Reachability analysis regards all objects and their reference relationships as a graph structure. From a certain node (GCroot node) to a certain node is connected, we say that this object is alive, otherwise, it is the object that needs to be recycled .

According to the in-depth understanding of the jvm book, there are the following objects that can be used as GCroots:

1. Objects referenced in the virtual machine stack (local variable table in the stack frame);

2. The object referenced by the class static property in the method area;

3. The object referenced by the constant in the method area;

4. The object referenced by JNI (that is, the native method in general) in the local method stack.

In fact, not only these four, but also class loaders and other objects can also be used as root nodes. Here's a piece of code:

public class StrongReference {
	public static void  main(String[] args) {
		//After executing this method, the person reference space is reclaimed, not pointing to the Person object, the object cannot be used as the root node, it should be reclaimed
		Person person = new Person(); //The object referenced in the virtual machine stack is the root node
		try {
			while(true){
				new ArrayList<Person>().add(person);
			}
		} catch (Throwable e) {
			person.printPerson ();
			throw e;
		}
		
	}
}

 Executing the above code, we find that this code loops forever and never throws an out-of-memory error. This is clearly not in line with our experience. The answer is simple: 
 

When executing new ArrayList<Person>().add(person); in the loop body , although ArrayList objects are constantly created in the heap, there is no reference chain from the root node person to the ArrayList, so the jvm will automatically recycle it This object, so even if you keep looping, there will be no memory overflow;

Modify the code as follows:

package reference;

import java.util.ArrayList;
import java.util.List;

public class StrongReference {
	public static void  main(String[] args) {
		//After executing this method, the person reference space is reclaimed, not pointing to the Person object, the object cannot be used as the root node, it should be reclaimed
		Person person = new Person(); //The object referenced in the virtual machine stack is the root node
		List<Person> list = new ArrayList<Person>();
		try {
			while(true){
				list.add(new Person());
			}
		} catch (Throwable e) {
			person.printPerson ();
			throw e;
		}
		
	}
}

Executing the above code, we find that this is person is output and an OutOfMemoryError error is thrown. This is because the list object is the root node, a reference in the list object points to the elementData array, and the elementData array stores the constantly generated person objects, so there is a reachable reference chain from the root node list object to the person object, so in the Before the method ends, the JVM will never recycle the person object, and an out-of-memory error occurs.

After a method is executed, the stack frame corresponding to the method is popped from the stack of the virtual machine, and the local variable table saved in the stack frame is also released. The object referenced by the original local variable loses the reference in the local variable and becomes Ordinary nodes, not root nodes, after becoming ordinary nodes, if there is no reachable reference chain with other root nodes, the object will also be recycled.


After talking about the gc mechanism of jvm, we are looking at the reference type in java. Since jdk1.2, java has expanded the concept of reference, divided into strong reference (StrongReference), soft reference (SoftReference), weak reference (WeakRefrnence) and virtual reference (PhantomReference) four. Let's talk about it separately:

1. Strong citations. The references generated by Object obj = new Object() are all strong references. As long as the strong reference still exists, the JVM will never reclaim the object.

2. Soft references. Soft references are mainly used to point to some useful but unimportant objects. If there is enough memory, the JVM will not reclaim the object pointed to by the soft reference. If the memory is tight, the JVM will reclaim the object before an overflow error occurs.

This can be used to implement caching of some persistent objects. For example, an object obtained from a query from a database may be used again after a period of time. By using a soft reference to associate it, frequent database queries can be avoided.

Don't worry about running out of memory. code show as below:

package reference;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

public class Soft_Reference {
	public static void main(String[] args) {
		SoftReference<Person> sf = new SoftReference<Person>(new Person());
		sf.get().printPerson(); //The person object information can be output at this time
		List<Person> list = new ArrayList<Person>();
		try {
			while(true){
				list.add(new Person());
			}
		} catch (Throwable e) {
			sf.get().printPerson();//Because of the memory overflow caused by the loop, the object pointed to by the soft reference has been recycled, and sf.get() returns null;
			throw e;
		}
	}
}
3. Weak references: Weak references are also used to describe non-essential objects, but their strength is weaker than soft references. Objects associated with weak references can only survive until the next garbage collection occurs.

package reference;

import java.lang.ref.WeakReference;

public class Weak_Reference {
	public static void main(String[] args) {
		WeakReference<Person> wr = new WeakReference<Person>(new Person());
		wr.get().printPerson();//Output information
		System.gc(); //gc mechanism starts working
		wr.get().printPerson(); //Because it has been recycled, a null pointer exception will occur
	}
}
4. Phantom references are also known as ghost references or phantom references. It is the weakest kind of reference relationship. Whether an object has a virtual reference will not affect its lifetime at all, and an object instance cannot be obtained through a virtual reference. The only purpose of setting a phantom reference association for an object is to receive a system notification when the object is reclaimed by the collector. After JDK 1.2, the PhantomReference class is provided to implement phantom references



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325942116&siteId=291194637