1. Strong reference
The references mentioned above in this chapter are actually strong references, which are the most common references. If an object has a strong reference, it is similar to an essential necessities. The garbage collector will never recycle it. When the memory space is insufficient, the Java virtual machine would rather throw an OutOfMemoryError to terminate the program abnormally and does not recycle strongly referenced objects to solve the problem of insufficient memory.
2. Soft reference)
If an object only has soft references, it is similar to the necessities that can be used. If the memory space is sufficient, the garbage collector will not recycle it. If the memory space is insufficient, the memory of these objects will be recycled. The object can be used by programs as long as the garbage collector does not recycle it. Soft references can be used to implement memory-sensitive high-speed cache.
Soft references can be used together with a ReferenceQueue, the Java Virtual Machine adds this soft reference to the reference queue associated with it.
3. WeakReference)
If an object only has weak references, it is similar to a necessities that can be used. The difference between weak references and soft references is that only objects with weak references have a shorter life cycle. When the garbage collector thread scans the memory area under its jurisdiction, its memory will be recycled no matter whether the current memory space is sufficient or not. However, since the garbage collector is a thread with a low priority, it may not soon find objects with weak references.
Weak references can be used together with a ReferenceQueue, the Java Virtual Machine adds this weak reference to the reference queue associated with it.
4. PhantomReference)
As the name implies, "virtual references" are just the same as virtual ones, which are different from other types of references. Virtual references do not determine the object lifecycle. If an object only holds a virtual reference, it is the same as no reference and may be recycled at any time.
Virtual references are mainly used to track the activity of objects being reclaimed by garbage collection. A difference between virtual and soft references and weak references is that virtual references must be used together with the reference queue (ReferenceQueue. When the zookeeper recycler is about to recycle an object, if it finds that it has a virtual reference, it will add this virtual reference to the reference queue associated with it before it recycles the object's memory. The program can know whether the referenced queue is added with virtual references.
Whether the referenced object is to be recycled. If the program finds that a virtual reference has been added to the reference queue, it can take necessary action before the memory of the referenced object is recycled.
In this book, "reference" can be either a verb or a noun. Readers should distinguish the meaning of "reference" based on context.
The java. lang. ref package provides three classes: SoftReference class, WeakReference class, and PhantomReference class, which represent soft reference, weak reference, and virtual reference respectively. The ReferenceQueue class indicates the reference queue. It can be used with these three reference classes to track the collection of referenced objects by the Java virtual machine. The following program creates a String object, ReferenceQueue object, and WeakReference object:
// Create a strong reference
String str = new String ("hello ");
// Create a reference queue. <String> indicates the reference of the String object in the queue.
ReferenceQueue <String> rq = new ReferenceQueue <String> ();
// Create a weak reference that references the "hello" object and is associated with the rq reference queue
// <String> It is a fan mark, indicating that WeakReference will weakly reference the String object
WeakReference <String> wf = new WeakReference <String> (str, rq );
After the code is executed, the relationship between the reference and the object in the memory is shown in Figure 11-10.
Figure 11-10 "hello" objects have both strong references and weak references
In Figure 11-10, arrows with solid lines represent strong references, and arrows with dotted lines represent weak references. As shown in the figure, the "hello" object is strongly referenced by str and weak referenced by a WeakReference object. Therefore, the "hello" object will not be recycled.
In the following program code, set the str variable that references the "hello" object to null, and then obtain the reference of the "hello" object through the WeakReference weak reference get () method:
String str = new String ("hello"); // ①
ReferenceQueue <String> rq = new ReferenceQueue <String> (); // ②
WeakReference <String> wf = new WeakReference <String> (str, rq); // ③
Str = null; // ④ cancel the strong reference of the "hello" object
String str1 = wf. get (); // ⑤ if the "hello" object is not recycled, str1 references the "hello" object
// If the "hello" object is not recycled, rq. poll () returns null.
Reference <? Extends String> ref = rq. poll (); // 6
After the forth row is executed, the relationship between the reference and the object in the memory is shown in Figure 11-11. At this time, the "hello" object only has weak references, so it may be recycled by garbage. If it has not been reclaimed by garbage collection, The wf. get () method executed in row ⑤ will return to the reference of the "hello" object and make the object highly referenced by str1. Then, when the rq. poll () method is executed in row 6, null is returned because no reference is provided in the reference queue. The poll () method of ReferenceQueue is used to return the reference in the queue. If not, null is returned.
Figure 11-11 "hello" objects only have weak references
In the following program code, after executing line 4, the "hello" object only has weak references. The next two calls the System. gc () method to urge the garbage collector to work, so as to increase the possibility that the "hello" object will be recycled. If the "hello" object is recycled, the reference of the WeakReference object is added to the ReferenceQueue, and then wf. the get () method returns null, and rq. the poll () method returns the reference of the WeakReference object. Figure 11-12 shows the relationship between the reference in the memory and the object after the execution of the nth row.
String str = new String ("hello"); // ①
ReferenceQueue <String> rq = new ReferenceQueue <String> (); // ②
WeakReference <String> wf = new WeakReference <String> (str, rq); // ③
Str = null; // ④
// Push the garbage collector twice to improve the possibility of "hello" objects being recycled
System. gc (); // ⑤
System. gc (); // ⑥
String str1 = wf. get (); // 7 if the "hello" object is recycled, str1 is null
Reference <? Extends String> ref = rq. poll (); // returns