Preface
This article tries to explore weak references in Java from the perspectives of What, Why, and How to help everyone understand the definitions, basic usage scenarios and usage methods of weak references in Java.
1. What--What is a weak quote?
Weak references in Java specifically refer to java.lang.ref.WeakReference<T> class. Let's first look at the official documentation explains it:
The existence of a weak reference object does not prevent the object it points to from being recycled by the garbage collector. The most common use of weak references is to implement canonicalizing mappings (such as hash tables).
Assuming that the garbage collector decides that an object is weakly reachable at a certain point in time (that is, all the current points to it are weak references), the garbage collector will clear all weak references to the object, and then mark the weak reachable object as finalizable, so that it will be recycled later. At the same time or later, the garbage collector will place the newly cleared weak references into the reference queue specified when creating the weak reference object.
In fact, there are four types of references in Java, which are from strong to weak: strong reference , soft reference , weak reference , and virtual reference .
Below we briefly introduce three other citations besides weak citations:
1. Strong Reference: Usually, the reference we return when we create a new object through new is a strong reference. If an object can be reached through a series of strong references, it is strongly reachable, then it will not be recycled.
2. Soft Reference: The difference between soft reference and weak reference is that if an object is reachable by a weak reference, it will be recycled regardless of whether the current memory is sufficient, while the object reachable by a soft reference will only be recycled when the memory is insufficient. Therefore, soft references are "stronger" than weak references.
3. Phantom Reference: Virtual reference is the weakest reference in Java, so how weak is it? It is so fragile that we cannot even get the referenced object through virtual references. The only purpose of virtual references is that when the object it points to is recycled, the virtual reference itself will be added to the reference queue and used to record that the object it points to has been recycled.
2. Why-Why-Why use weak references?
Consider the following scenario: There is now a Product class that represents a product, which is designed to be non-scalable, and at this time we want to add a number to each product. One solution is to use HashMap<Product, Integer> . So the problem comes. If we no longer need a Product object to exist in memory (for example, this product has been sold), assuming that the reference to it is productA , we will assign a value to productA as null . However, at this time, the Product object pointed to by productA in the past will not be recycled, because it is obviously referenced by HashMap . So in this case, if we want to truly recycle a Product object, it is not enough to just assign its strong reference to null , and we also need to remove the corresponding entry from HashMap . Obviously, we don't want to complete the work of "removing no longer needed entries from HashMap " by ourselves. We want to tell the garbage collector: only key in HashMap references Product object, the corresponding Product object can be recycled. Obviously, based on the previous definition of weak citations, using weak citations can help us achieve this goal. We just need to use a weak reference object pointing to Product object as key in HashMap .
3. How--How to use weak references?
Take the scenario introduced above as an example. We use a weak reference object pointing to Product object as key of HashMap , and just define this weak reference object like this:
Product productA = new Product(...);WeakReference<Product> weakProductA = new WeakReference<>(productA);
Now, if the object weakProductA is referenced, it points to Product object productA . So how do we get Product object productA that it points to through weakProduct ?
It's very simple, just need the following code:
Product product = weakProductA.get();
In fact, for this case, the Java class library provides us with the WeakHashMap class. Using this class, its key is naturally a weak reference object, and we no longer need to manually wrap the original object. In this way, when productA becomes null (it indicates that Product it references no longer needs to exist in memory), Product weak reference object is weakProductA , then obviously the corresponding Product object is weak and can be reached at this time, so the weak reference pointing to it will be cleared, and the Product object will be recycled, and the weak reference pointing to it will enter the reference queue.
4. Reference queue
Let’s briefly introduce the concept of citing queues. In fact, the WeakReference class has two constructors:
//Create a weak reference to the given object WeakReference(T reference) //Create a weak reference to the given object and registers a weak reference to the given reference queue WeakReference(T reference, ReferenceQueue<? super T> q)
We can see that the second constructor provides a parameter of type ReferenceQueue . By providing this parameter, we register the created weak reference object on a reference queue. In this way, when it is cleared by the garbage collector, it will be sent to the reference queue, and we can manage these cleaned weak reference objects in a unified manner.
5. Summary
Well, the content of this article ends here. Due to the limited personal level, there are inevitably inaccurate or unclear aspects in the narrative. I hope you can point it out, thank you for your support for Wulin.com.