Explain in detail the understanding and use of Java weak reference of WeakReference

  • 2021-07-13 05:16:46
  • OfStack

When I saw a post, When a foreign technical interviewer interviewed senior java developer, Asked a question about weak reference. He did not expect anyone to fully explain what weak reference was, How to use it, I just expect someone to mention that this concept is related to GC of java. Unfortunately, Among more than 20 interviewers with more than 5 years' experience in java development, Only two people know the existence of weak reference, And only one of them actually used him. Undoubtedly, in the eyes of interviewer, the understanding and application of weak and reference gave this one interviewee quite a lot of bonus points in the interview. Therefore, I summarize my understanding and use of this technology in this blog, hoping that readers and themselves can get bonus points in future work and interviews by reading and writing this post.

In Java, when an object o is created, it is placed in Heap. When GC is running, o is reclaimed to free up memory space if no references are found to point to o. Or in other words, an object is reclaimed only if two conditions are met: 1) No references point to it 2) GC is running.

In the real world, we often write code by leaving all referece pointing to an object blank to ensure that the object is reclaimed the next time GC is run. (You can use java-verbose: gc to observe the behavior of gc.)


Object c = new Car();
c=null;

However, manually nulling an object is tedious for programmers and goes against the idea of automatic recycling. For simple cases, manually nulling is unnecessary for programmers, because in java, for a simple object, when the method calling it is executed, the reference pointing to it will be recycled from popup in stack, so it can be recycled in the next GC execution.

However, there are special exceptions. When using cache, Because the objects of cache are just what the program needs to run, So as long as the program is running, The references in cache will not be given by GC (or reference in cache has life cycle like the main program 1). Then as reference in cache increases, so does object that cannot be recycled by GC, which cannot be automatically recycled. When these object need to be recycled, the task of recycling these object is left to the programmer. However, this violates the essence of GC (automatic recycling of recyclable objects).

Therefore, weak reference is introduced in java. Compared with strong reference in the previous example:


Object c = new Car(); // As long as c Also points to car object, car object It won't be recycled 

When an object is only pointed to by weak reference and no other strong reference, the object is recycled if GC is running. The syntax for weak reference is:

WeakReference < Car > weakCar = new WeakReference(Car)(car);

When you want to get the object referenced by weak reference, you first need to determine whether it has been recycled:

weakCar.get();

If this method is empty, the object pointed to by weakCar has been recycled.

Let's look at an example:


package weakreference;
/**
 * @author wison
 */
public class Car {
	private double price;
	private String colour;
	
	public Car(double price, String colour){
		this.price = price;
		this.colour = colour;
	}
	
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public String getColour() {
		return colour;
	}
	public void setColour(String colour) {
		this.colour = colour;
	}
	
	public String toString(){
		return colour +"car costs $"+price;
	}
	
}

package weakreference;

import java.lang.ref.WeakReference;

/**
 * @author wison
 */
public class TestWeakReference {

	
	public static void main(String[] args) {
		
		Car car = new Car(22000,"silver");
		WeakReference<Car> weakCar = new WeakReference<Car>(car);
		int i=0;
		while(true){
			if(weakCar.get()!=null){
				i++;
				System.out.println("Object is alive for "+i+" loops - "+weakCar);
			}else{
				System.out.println("Object has been collected.");
				break;
			}
		}
	}

}

In the above example, after running the program for 1 period of time, the program prints out "Object has been collected.", indicating that the object pointed to by weak reference has been recycled.

One notable point is that even if there is an car reference pointing to an object and car is an strong reference, the object pointed to by weak reference weakCar is still recycled. This is because the compiler of java found that car was no longer used after entering the while loop, so it was optimized (leave it empty? ). When TestWeakReference. java is amended to read:


package weakreference;

import java.lang.ref.WeakReference;

/**
 * @author wison
 */
public class TestWeakReference {

	public static void main(String[] args) {
		
		Car car = new Car(22000,"silver");
		WeakReference<Car> weakCar = new WeakReference<Car>(car);
		
		int i=0;
		
		while(true){
			System.out.println("here is the strong reference 'car' "+car);
			if(weakCar.get()!=null){
				i++;
				System.out.println("Object is alive for "+i+" loops - "+weakCar);
			}else{
				System.out.println("Object has been collected.");
				break;
			}
		}
	}

}

The object pointed to by weak reference will not be recycled because there is another strong reference car pointing to it.

* One of the characteristics of WeakReference is that when it will be recycled is uncertain, because this is determined by the uncertainty of GC's operation. Therefore, objects referenced by weak reference are valuable objects referenced by cache, and can be easily rebuilt and consume memory.

ReferenceQueue

After the objects pointed to by weak reference are recycled, weak reference itself is useless. java provides an ReferenceQueue to hold the recycled reference of the objects pointed to. Usage is to pass an ReferenceQueue object as a parameter to the constructor when defining WeakReference.

Other types of references

-SoftReference

soft reference and weak reference1, but when it is recycled by GC, one more condition is needed: when the system memory is insufficient (how does GC judge that the system memory is insufficient? Is there a parameter to configure this threshold? ), the object pointed to by soft reference will be recycled. Because of this feature, soft reference is more suitable as reference of cache objects than weak reference. Because it can make retain cached objects as much as possible, it can reduce the time and consumption required to rebuild them.


Related articles: