Strong, soft, weak and phantom references to objects

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.

  

Strong Reference

  Strong references are the most commonly used references. 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. 

   ps: Strong reference is actually what we usually mean by A a = new A().

 

Soft Reference

  Soft references are weaker than strong references and are represented by the class SoftReference . Its role is to tell the garbage collector which objects in the program are less important and can be temporarily reclaimed when memory is insufficient. When the JVM runs out of memory, the garbage collector frees objects that are only pointed to by soft references. If the memory is not enough after all these objects are released, an OutOfMemory error will be thrown. Soft references are great for creating caches. When the system memory is insufficient, the content in the cache can be released.

  Consider, for example, an image editor program. The program will read the entire contents of the image file into memory for easy processing. The user can also open multiple files at the same time. When there are too many files open at the same time, it may cause insufficient memory. If soft references are used to point to the contents of the image file, the garbage collector can reclaim the memory when necessary.

copy code
public class ImageData {
    private String path;
    private SoftReference<byte[]> dataRef;
    public ImageData(String path) {
        this.path = path;
        dataRef = new SoftReference<byte[]>(new byte[0]);
    }
    private  byte [] readImage() {
         return  new  byte [1024 * 1024]; // The operation of reading the file is omitted
    }
    public byte[] getData() {
        byte[] dataArray = dataRef.get();
        if (dataArray == null || dataArray.length == 0) {
            dataArray = readImage();
            dataRef = new SoftReference<byte[]>(dataArray);
        }
        return dataArray;
    }
}
copy code

  When running the above program, you can use the  -Xmx  parameter to limit the memory available to the JVM. Since the object pointed to by the soft reference may be recycled, when obtaining the object actually pointed to by the soft reference through the get method, it is always necessary to check whether the object is still alive.

Weak Reference (WeakReference)  

  Weaker in strength than soft references, represented by the class WeakReference . Its role is to reference an object, but it does not prevent the object from being recycled. If a strong reference is used, as long as the reference exists, the referenced object cannot be collected. Weak references do not have this problem. When the garbage collector is running, if all references to an object are weak references, the object will be collected. The role of weak references is to solve the coupling relationship between objects in terms of lifetime caused by strong references. The most common use of weak references is in collection classes, especially hash tables. The hash table interface allows any Java object to be used as a key. When a key-value pair is put into a hash table, the hash table object itself has references to those key and value objects. If this reference is a strong reference, as long as the hash table object itself is alive, the key and value objects contained in it will not be recycled. If a long-lived hash table contains many key-value pairs, it may eventually consume all the memory in the JVM.

  The solution to this situation is to use weak references to refer to these objects, so that both the key and value objects in the hash table can be garbage collected. WeakHashMap is provided in Java to meet this common need.

 

PhantomReference

  Before introducing ghost references, we must first introduce the object finalization mechanism (finalization) provided by Java. There is a finalize method in the Object class , which is designed to perform some cleanup work before an object is actually recycled. Because Java does not provide the same mechanism as C++'s destructor, it is implemented through the finalize method. But the problem is that the running time of the garbage collector is not fixed, so the actual running time of these cleanups is also unpredictable. A phantom reference can solve this problem. A reference queue must be specified when creating a PhantomReference . When an object's finalize method has been called, ghost references to that object are added to the queue. By checking the contents of the queue, it is known whether an object is ready to be recycled.

  Spectre references and their queues are rarely used, and are mainly used to implement finer memory usage control, which is very meaningful for mobile devices. A program can allocate memory to create a new object after determining that an object is to be reclaimed. In this way, the memory consumed by the program can be kept at a relatively low amount. For example, the following code gives an example of the implementation of a buffer.

copy code
public class PhantomBuffer {
  private byte[] data = new byte[0];
    private ReferenceQueue<byte[]> queue = new ReferenceQueue<byte[]>();
    private PhantomReference<byte[]> ref = new PhantomReference<byte[]>(data, queue);
    public byte[] get(int size) {
        if (size <= 0) {
            throw new IllegalArgumentException("Wrong buffer size");
        }
        if (data.length < size) {
            data = null;
            System.gc(); // Force the garbage collector to run 
             try {
                queue.remove(); // This method will block until the queue is not empty 
                ref.clear(); // The ghost reference will not be cleared automatically, you need to run 
                ref = null manually ;
                data = new byte[size];
                ref = new PhantomReference<byte[]>(data, queue);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
       }
       return data;
    }
}
copy code

  In the above code, every time you apply for a new buffer, first ensure that the byte array of the previous buffer has been successfully recycled. The remove method of the reference queue blocks until a new ghost reference is added to the queue. However, it should be noted that this approach will cause the garbage collector to be run too many times, which may cause the throughput of the program to be too low.

 

 

reference queue

 

  In some cases, the program will need to be notified when the reachability of an object changes. For example, strong references to an object no longer exist, and only soft references or weak references remain. But there is still some work to do with the reference itself. A typical scenario is in a hash table. The reference object is used as the key object in the WeakHashMap. When the actual object it refers to is garbage collected, the key-value pair needs to be deleted from the hash table. With the reference queue ( ReferenceQueue ), you can easily get these weak reference objects and delete them from the table. Before soft and weak reference objects are added to the queue, their references to the actual objects are automatically cleared. Through the poll / remove method of the reference queue, the reference object in the queue can be obtained in a non-blocking and blocking way, respectively

 

Guess you like

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