Article From:https://www.cnblogs.com/pypua/p/9967551.html

Presumably, many friends are familiar with the error of OOM (OutOfMemory), and how to solve this problem effectively when encountering this error? Today, let’s talk about how to use soft and weak references to effectively solve OOM problems in programs. The following is the catalogue of this article.Outline:

  1. Understanding the concepts of strong citation, soft citation, weak citation and virtual citation

  2. Further Understanding of Soft Reference and Weak Reference

  3. How to Solve OOM Problem by Soft Reference and Weak Reference

  If there are any mistakes, I would appreciate your understanding and criticism.

1. Understand the concepts of strong citation, soft citation, weak citation and virtual citation.

In Java, although programmers are not required to manage the life cycle of objects manually, soft references and weak references are needed if some objects are expected to have a certain life cycle (e.g., when memory is insufficient, JVM will automatically reclaim some objects to avoid OutOfMemory errors).Yes.

Since Java SE2, four types of references have been provided: strong references, soft references, weak references and virtual references. There are two main purposes for providing these four types of references in Java: first, to enable programmers to determine the lifecycle of certain objects by means of code; and second, to facilitate JVM entry.Garbage recycling. Next, the concepts of these four types of references are elaborated.

1.Strong Reference

  Strong references are common in program code. For example, both object and STR in the following code are strong references:

Object object = new Object();
String str = "hello";

As long as an object has a strong reference associated with it, the JVM will not reclaim the object, and even in case of insufficient memory, the JVM would rather throw an OutOfMemory error than reclaim the object. For example, here’s the code

public class Main {
   public static void main(String[] args) {
       new Main().fun1();
   }
    
   public void fun1() {
       Object object = new Object();
       Object[] objArr = new Object[1000];
   }
}

If you want to break the association between a strong reference and an object, you can explicitly assign the reference to null, so that the JVM will reclaim the object at the right time. When running to Object [] objArr = new Object [1000];In this case, if there is insufficient memory, the JVM will throw an OOM error and will not reclaim the object pointed to. Note, however, that when fun1 runs out, both object and objArr no longer exist, so the objects they point to are recycled by the JVM.

  For example, in the clearing method of the Vector class, the cleanup is achieved by assigning a reference to null:

/**
    * Removes the element at the specified position in this Vector.
    * Shifts any subsequent elements to the left (subtracts one from their
    * indices).  Returns the element that was removed from the Vector.
    *
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    *         ({@code index < 0 || index >= size()})
    * @param index the index of the element to be removed
    * @return element that was removed
    * @since 1.2
    */
   public synchronized E remove(int index) {
   modCount++;
   if (index >= elementCount)
       throw new ArrayIndexOutOfBoundsException(index);
   Object oldValue = elementData[index];

   int numMoved = elementCount - index - 1;
   if (numMoved > 0)
       System.arraycopy(elementData, index+1, elementData, index,
                numMoved);
   elementData[--elementCount] = null; // Let gc do its work

   return (E)oldValue;
   }

2.SoftReference

  Soft references are used to describe some useful but not necessary objects, which are represented in Java by java. lang. Ref. SoftReference classes. For objects associated with soft references, the JVM will only reclaim the object when there is insufficient memory. Therefore, this pointIt can be used to solve the problem of OOM, and this feature is very suitable for caching: web page caching, image caching, etc.

Soft references can be used in conjunction with a Reference Queue, and if the object referenced by a soft reference is reclaimed by the JVM, the soft reference is added to the reference queue associated with it. Here is an example of how to use:

import java.lang.ref.SoftReference;

public class Main {
   public static void main(String[] args) {
        
       SoftReference<String> sr = new SoftReference<String>(new String("hello"));
       System.out.println(sr.get());
   }
}

3.WeakReference

  Weak references are also used to describe non-essential objects. When the JVM collects garbage, the objects associated with the weak references will be recovered regardless of whether the memory is sufficient or not. In java, it is represented by the java. lang. Ref. WeakReference class. The following is an example of use:

import java.lang.ref.WeakReference;

public class Main {
   public static void main(String[] args) {
    
       WeakReference<String> sr = new WeakReference<String>(new String("hello"));
        
       System.out.println(sr.get());
       System.gc();                //Notify the GC of the JVM for garbage collection
       System.out.println(sr.get());
   }
}

The output results are as follows:

hello
null

The second output is null, which means that as long as the JVM does garbage collection, objects associated with weak references must be recycled. However, it should be noted that the object associated with weak references here refers to garbage collection if only weak references are associated with them, and if there are strong references associated with them at the same time.This object is not reclaimed (as is the case with soft references).

  Weak references can be used in conjunction with a Reference Queue, and if the object referenced by a weak reference is reclaimed by the JVM, the soft reference is added to the reference queue associated with it.

4.Phantom Reference

  Unlike previous soft and weak references, virtual references do not affect the life cycle of objects. In java, it is represented by the java. lang. Ref. PhantomReference class. If an object is associated with a virtual reference, it is the same as if no reference is associated with it, in any caseIt can be recycled by the garbage collector at any time.

  It should be noted that virtual references must be used in conjunction with reference queues. When the garbage collector is ready to recycle an object, if it finds that it has a virtual reference, it will add the virtual reference to the reference queue associated with it. Programs can learn to be cited by determining whether virtual references have been added to the reference queue.Will the object used be garbage collected? 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. Further Understanding of Soft Reference and Weak Reference                                              

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;


public class Main {
   public static void main(String[] args) {
       ReferenceQueue<String> queue = new ReferenceQueue<String>();
       PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
       System.out.println(pr.get());
   }
}

For strong references, we often use them when writing code. For the other three types of references, the most frequently used are soft and weak references, which have similarities and differences. They are all used to describe non-essential objects, but objects associated with soft references are only used when memory is insufficient.It is recycled, and objects associated with weak references are always recycled when the JVM does garbage collection.

  In the SoftReference class, there are three methods, two construction methods and one get method (similar to WekReference):

  Two construction methods:

public SoftReference(T referent) {
   super(referent);
   this.timestamp = clock;
   }

public SoftReference(T referent, ReferenceQueue<? super T> q) {
   super(referent, q);
   this.timestamp = clock;
   }

When using soft and weak references, we can explicitly notify JVM of garbage collection through System. GC (), but it is important to note that although the notification is given, the JVM will not necessarily execute immediately, that is to say, this sentence can not ensure that the JVM will garbage collection at this time.. The get method is used to get a reference to an object associated with a soft reference and return null if the object is reclaimed.

3. How to Solve OOM Problem by Soft Reference and Weak Reference

The basic knowledge about soft references and weak references was mentioned earlier, so how to use them to optimize program performance and avoid OOM problems?

  For example, if an application needs to read a large number of local pictures, if every time it reads pictures from the hard disk, it will seriously affect the performance, but if all the pictures are loaded into memory, it may cause memory overflow. At this time, using soft reference can solve this problem.

The design idea is to use a HashMap to save the mapping relationship between the path of the image and the soft reference associated with the corresponding image object. When the memory is insufficient, JVM will automatically recover the space occupied by these cached image objects, thus effectively avoiding the problem of OOM. At AndroidA lot of picture downloads are often used in development.

  The following code is extracted from the blog:

  http://blog.csdn.net/arui319/article/details/8489451

.....
private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
<br>....
public void addBitmapToCache(String path) {

       // Strongly referenced Bitmap objects

       Bitmap bitmap = BitmapFactory.decodeFile(path);

       // Soft-referenced Bitmap objects

       SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);

       // Add the object to the Map to cache it

       imageCache.put(path, softBitmap);

   }

public Bitmap getBitmapByPath(String path) {

       // Extracting Soft Referenced Bitmap Objects from Cache

       SoftReference<Bitmap> softBitmap = imageCache.get(path);

       // Judging whether there are soft references

       if (softBitmap == null) {

           return null;

       }

       // Remove the Bitmap object. If Bitmap is reclaimed due to insufficient memory, it will be empty.

       Bitmap bitmap = softBitmap.get();

       return bitmap;

   }

Reference material:

《Deep Understanding of JVM Virtual Machine

http://blog.csdn.net/arui319/article/details/8489451  

http://blog.csdn.net/zsuguangh/article/details/6429592

http://mobile.51cto.com/abased-406998.htm

Leave a Reply

Your email address will not be published. Required fields are marked *