Java strong reference, soft reference, weak reference, virtual reference

1. Strong, soft, weak and phantom references
    to objects In versions prior to JDK 1.2, if an object was not referenced by any variable, the program could no longer use the object. That is, the program can only use the object if it is in the reachable state. Since JDK 1.2 version, the reference of objects is divided into four levels, so that the program can control the life cycle of the object more flexibly. The 4 levels from high to low are: strong reference, soft reference, weak reference and virtual reference.

Figure 1 is the object application class hierarchy
1) Strong reference (StrongReference)
    Strong reference is the most common reference used. If an object has a strong reference, the garbage collector will never collect it. When the memory space is insufficient, the Java virtual machine would rather throw an OutOfMemoryError error to cause the program to terminate abnormally, rather than solve the problem of insufficient memory by arbitrarily reclaiming objects with strong references.
 
2) Soft Reference (SoftReference)
    If an object has only soft references, the memory space is sufficient, and the garbage collector will not reclaim it; if the memory space is insufficient, the memory of these objects will be reclaimed. The object can be used by the program as long as it is not collected by the garbage collector. Soft references can be used to implement memory-sensitive caches (examples are given below).
    Soft references can be used in conjunction with a reference queue (ReferenceQueue). If the object referenced by the soft reference is reclaimed by the garbage collector, the Java virtual machine will add the soft reference to the associated reference queue.

3) Weak Reference (WeakReference)
    The difference between a weak reference and a soft reference is that objects with weak references have a shorter life cycle. In the process of scanning the memory area under the jurisdiction of the garbage collector thread, once an object with only weak references is found, its memory will be reclaimed regardless of whether the current memory space is sufficient or not. However, since the garbage collector is a very low-priority thread, objects that only have weak references will not necessarily be discovered quickly.
    Weak references can be used in conjunction with a reference queue (ReferenceQueue). If the object referenced by the weak reference is garbage collected, the Java virtual machine will add the weak reference to the associated reference queue.

 4) PhantomReference (PhantomReference)
    "PhantomReference", as the name suggests, is just in name only. Unlike other references, PhantomReference does not determine the life cycle of an object. If an object only holds phantom references, then it can be collected by the garbage collector at any time as if it had no references at all.
Phantom references are primarily used to track the activity of objects being reclaimed by the garbage collector. One difference between virtual references and soft references and weak references is that virtual references must be used in conjunction with reference queues. When the garbage collector is ready to reclaim an object, if it finds that it still has a virtual reference, it will add the virtual reference to the reference queue associated with it before reclaiming the memory of the object.
 
    The program can know whether the referenced object is about to be garbage collected by judging whether a virtual reference has been added to the reference queue. If the program finds that a virtual reference has been added to the reference queue, it can take the necessary action before the memory of the referenced object is reclaimed.
2. Judgment of object accessibility
    In many cases, an object is not directly referenced from the root set, but an object is referenced by other objects, or even referenced by several objects at the same time, thus forming a root set as the top. tree structure. as shown in picture 2

    In this tree-shaped reference chain, the direction of the arrow represents the direction of the reference, and the object pointed to is the referenced object. As can be seen from the figure, there can be many paths from the root set to an object. For example, there are two paths to reach object 5: ①-⑤ and ③-⑦. This brings about a problem, that is, how to judge the reachability of an object:
single reference path reachability judgment: In this path, the weakest reference determines the reachability of the object.
Reachability judgment of multiple reference paths: Among several paths, the reference of the strongest one determines the reachability of the object.
    For example, we assume that references ① and ③ in Figure 2 are strong references, ⑤ are soft references, and ⑦ are weak references. For object 5, according to these two judgment principles, the paths ①-⑤ take the weakest reference ⑤, so the path is right The reference to object 5 is a soft reference. Similarly, ③-⑦ are weak references. The strongest reference is taken between these two paths, so object 5 is a soft reachable object.


3. Use soft references to build a cache of sensitive data
3.1 Why do you need to use soft references
   First, let's look at an example of an employee information query system. We will use an employee information query system implemented in Java language to query employee personnel file information stored in a disk file or database . As a user, it's entirely possible that we need to go back and view employee profile information that we viewed minutes or even seconds ago (similarly, we often use the "back" button when browsing web pages). At this time, we usually have two program implementation methods: one is to save the employee information viewed in the past in memory, and the life cycle of each Java object that stores employee profile information runs through the entire application; the other is to When the user starts to view the file information of other employees, end the reference to the Java object that stores the currently viewed employee file information, so that the garbage collection thread can reclaim the memory space occupied by it, and when the user needs to browse the file of the employee again information, reconstruct the employee's information. Obviously, the first implementation method will cause a lot of memory waste, and the second implementation has the disadvantage that even if the garbage collection thread has not been garbage collected, the object containing the employee file information is still well preserved in memory, and the application is also To rebuild an object. We know that operations such as accessing disk files, accessing network resources, and querying databases are all important factors that affect the execution performance of applications. If we can re-acquire the references of those Java objects that have not been recycled, unnecessary access will be reduced and greatly improved. The speed at which the program runs.

 
3.2 If a soft reference is used
    SoftReference is characterized in that one of its instances holds a soft reference to a Java object, the existence of the soft reference does not prevent the garbage collection thread from recycling the Java object. That is to say, once the SoftReference saves a soft reference to a Java object, the get() method provided by the SoftReference class returns a strong reference to the Java object before the garbage thread recycles the Java object. Also, the get() method will return null once the Java object is reclaimed by the garbage thread. Look at the following code:
1
MyObject aRef = new MyObject();
2
SoftReference aSoftRef = new SoftReference( aRef );
    At this point, for this MyObject object, there are two reference paths, one is the soft reference from the SoftReference object, and the other is from the variable aRef A strong reference, so this MyObject object is a strongly reachable object.
    Immediately, we can end aRef's strong reference to this MyObject instance:
1
aRef = null ;
    Thereafter, the MyObject object becomes a soft reachable object. If the garbage collection thread performs memory garbage collection, the object will not always be retained because there is a SoftReference to the object. The garbage collection thread of the Java virtual machine treats soft reachable objects differently from other general Java objects: the cleanup of soft reachable objects is determined by the garbage collection thread according to its specific algorithm according to memory requirements. That is to say, the garbage collection thread will reclaim soft reachable objects before the virtual machine throws OutOfMemoryError, and the virtual machine will give priority to reclaiming soft reachable objects that have been idle for a long time as much as possible. For those soft reachable objects that have just been constructed or just used Reach objects are preserved as much as possible by the virtual machine. Before recycling these objects, we can     regain a strong reference to the instance by:
1
MyObject anotherRef = (MyObject) aSoftRef .get() .
After recycling, calling the get() method can only get null.
 
3.3 Use ReferenceQueue to clear the SoftReference that has lost the soft reference object
    As a Java object, the SoftReference object has the generality of Java objects in addition to the speciality of saving soft references. Therefore, after the soft reachable object is recycled, although the get() method of the SoftReference object returns null, the SoftReference object no longer has the value of existence, and an appropriate clearing mechanism is needed to avoid the memory brought by a large number of SoftReference objects. leakage. ReferenceQueue is also provided in the java.lang.ref package. If a ReferenceQueue object is used as a parameter to provide the SoftReference constructor when creating the SoftReference object, such as:
1
ReferenceQueue queue = new ReferenceQueue();
2
SoftReference ref = new SoftReference( aMyObject , queue );
    Then when the aMyOhject soft referenced by this SoftReference is recycled by the garbage collector, the SoftReference object strongly referenced by ref is listed in the ReferenceQueue. That is to say, the object saved in the ReferenceQueue is a Reference object, and it is a Reference object that has lost the object to which it is softly referenced. In addition, it can be seen from the name ReferenceQueue that it is a queue. When we call its poll() method, if the queue is not an empty queue, the Reference object in front of the queue will be returned.
    At any time, we can call the poll() method of the ReferenceQueue to check whether any non-strongly reachable objects it cares about have been collected. If the queue is empty, it will return a null, otherwise the method returns a Reference object in front of the queue. Using this method, we can check which SoftReference soft-referenced objects have been reclaimed. So we can clear these SoftReference objects that lose the soft referenced objects. The common way is:
1
SoftReference ref = null ;
2
while ((ref = (SoftReference)q .poll()) != null ) {
3
     // Clear ref
4
}
After understanding the working mechanism of ReferenceQueue, we can start Constructs a cache of Java objects.
 
3.4 Cache Java objects through soft-accessible object retrieval methods
    Using the characteristics of the Java2 platform's garbage collection mechanism and the aforementioned garbage object recovery method, we use a small example of an employee information query system to illustrate how to build a cache to avoid the performance loss caused by repeatedly building the same object. We define an employee's profile information as an Employee class:
01
public class Employee {
02
     private String id ; // employee's identification number
03
     private String name ; // employee name
04
     private String department ; // the employee's department
05
     private String Phone ; // the employee's contact phone number
06
     private int salary ; // the employee's salary
07
     private String origin ; // the source of the employee's information
08
 
09
     // constructor
10
     public Employee(String id) {
11
        this . id = id;
12
       getDataFromlnfoCenter();
13
    }
14
 
15
     // Get employee information from the database
16
     private void getDataFromlnfoCenter() {
17
        // Establish a connection with the database and query the employee's information, assign the query result to
18
        // Assign variables such as name, department, plone, salary, etc.
19
        // At the same time, assign the origin value to "From DataBase"
20
    }
21
...
22
} In
the constructor of this Employee class, we can foresee that if we need to query the information of one employee each time. Even if it is just queried a few seconds ago, it takes a lot of time to rebuild an instance. The following is the definition of a cache that caches Employee objects:
 
01
import java.lang.ref.ReferenceQueue;
02
import java.lang.ref.SoftReference;
03
import java.util.Hashtable;
04
 
05
public class EmployeeCache {
06
     static private EmployeeCache cache ; // A Cache instance
07
     private Hashtable<String, EmployeeRef> employeeRefs ; // Storage for Chche content
08
     private ReferenceQueue<Employee> q ; // Queue of garbage Reference
09
 
10
     // Inherit SoftReference, making Each instance has a recognizable identity,
11
     // and the identity is the same as its key in the HashMap.
12
     private class EmployeeRef extends SoftReference<Employee> {
13
        private String _key = "" ;
14
 
15
        public EmployeeRef(Employee em, ReferenceQueue<Employee> q) {
16
            super (em, q);
17
            _key = em.getID();
18
       }
19
    }
20
 
21
     // construct a cache instance
22
     private EmployeeCache() {
23
        employeeRefs = new Hashtable<String,EmployeeRef>();
24
        q = new ReferenceQueue<Employee>();
25
    }
26
 
27
     // get the cache instance
28
     public static synchronized EmployeeCache getInstance() {
29
       if (cache == null){
30
            cache = new EmployeeCache();
31
       }
32
       return cache ;
33
    }
34
 
35
     // Perform a soft reference to an instance of an Employee object cite and save that citation
36
     private void cacheEmployee(Employee em) {
37
       cleanCache(); // clear garbage references
38
       EmployeeRef ref = new EmployeeRef(em, q );
39
        employeeRefs .put(em.getID(), ref);
40
    }
41
 
42
     //
43
     public Employee getEmployee(String ID) {
44
       Employee em = null ;
45 // Whether there is a soft reference to
        the Employee instance in the cache, if so, from the soft reference get.
46
        if ( employeeRefs .containsKey(ID)) {
47
           EmployeeRef ref = (EmployeeRef) employeeRefs .get(ID);
48
           em = (Employee) ref.get();
49
       }
50
        // If there is no soft reference, or the instance obtained from the soft reference is null, rebuild an instance,
51
        // and save the soft reference to the newly created instance
52
        if (em == null ) {
53
           em = new Employee (ID);
54
           System.out .println( "Retrieve From EmployeeInfoCenter. ID=" + ID);
55
            this .cacheEmployee(em);
56
       }
57
        return em;
58
    }
59
 
60
     // Clear those soft references to Employee EmployeeRef object whose object has been reclaimed
61
     private void cleanCache() {
62
       EmployeeRef ref = null ;
63
        while ((ref = (EmployeeRef) q .poll()) != null ) {
64
            employeeRefs .remove(ref. _key );
65
       }
66
    }
67
}
Author: Patriots

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326841548&siteId=291194637