Presumably many friends of Oom (outofmemory) This error is not unfamiliar, and when encountered this error how to effectively solve the problem? Today we are going to say how to use soft references and weak references to effectively resolve oom problems that arise in a program.
I. Understanding the concepts of strong references, soft references, weak references, virtual references
In Java, although programmers do not need to manually manage the lifecycle of objects, soft references and weak references are needed if you want certain objects to have a certain lifecycle (such as when the JVM automatically reclaims some objects to avoid outofmemory errors) when there is not enough memory.
Starting with the Java SE2, there are four types of references: Strong references, soft references, weak references, and virtual references. There are two main purposes for providing these four types of references in Java: The first is to allow programmers to determine the life cycle of certain objects in code, and second, to facilitate garbage collection by the JVM. Here are some ideas for the four types of references:
1. Strong references (strongreference)
Strong references are common in program code, such as the object and STR in the following code are strong references:
As long as an object has a strong reference associated with it, the JVM must not recycle the object, even if there is not enough memory, the JVM would rather throw a outofmemory error than recycle the object. For example, the following code:
public class Main {public
static void Main (string[] args) {
new Main (). FUN1 ();
}
public void Fun1 () {
object = new Object ();
object[] Objarr = new object[1000];
}
When running to object[] Objarr = new object[1000]; if there is not enough memory, the JVM throws Oom error and does not reclaim objects that object points to. Note, however, that when the fun1 is finished, both object and Objarr no longer exist, so the objects they point to are recycled by the JVM.
If you want to break the association between a strong reference and an object, you can show that the reference is assigned null, so that the JVM reclaims the object at the right time.
For example, in the clear method of a vector class, the cleanup is done by assigning the 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 is 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 is removed
* @return element that is 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 does its work return
(E) oldValue;
}
2. Soft Reference (SoftReference)
Soft references are used to describe some useful but not necessary objects, expressed in Java by the Java.lang.ref.SoftReference class. For objects associated with a soft reference, the JVM reclaims the object only when there is not enough memory. Therefore, this can be a good solution to the problem of oom, and this feature is suitable for caching: such as Web caching, image caching, and so on.
Soft references can be used in conjunction with a reference queue (Referencequeue), and a soft reference is added to the associated reference queue if the object referenced by the soft reference is reclaimed by the JVM. The following is a sample usage:
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. Weak reference (WeakReference)
Weak references are also used to describe non-essential objects, and objects associated with weak references are reclaimed when the JVM is garbage collected, regardless of whether memory is sufficient. In Java, this is represented by the Java.lang.ref.WeakReference class. The following is a sample usage:
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 (); Notifies the JVM of GC for garbage collection
System.out.println (Sr.get ());
}
The output results are:
Hello
Null
The second output is null, which means that the object associated with the weak reference must be recycled as long as the JVM is garbage collected. Note, however, that the object that is associated with a weak reference here is that only a weak reference is associated with it, and if a strong reference is associated with it, the object is not reclaimed (as is the case with the soft reference) when it is garbage collected.
A weak reference can be used in conjunction with a reference queue (Referencequeue), and a soft reference is added to the associated reference queue if the object referenced by the weak reference is reclaimed by the JVM.
4. Virtual Reference (Phantomreference)
A virtual reference differs from a previous soft reference or weak reference, and does not affect the object's lifecycle. Represented in Java with the Java.lang.ref.PhantomReference class. If an object is associated with a virtual reference, it is likely to be reclaimed by the garbage collector at any time, as is the case with no reference to it.
Note that a virtual reference must be associated with a reference queue, and when the garbage collector is ready to recycle an object, if it finds a virtual reference, it adds the virtual reference to the reference queue associated with it. A program can determine whether a referenced object will be garbage collected by determining 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, you can take the necessary action before the memory of the referenced object is reclaimed.
Import java.lang.ref.PhantomReference;
Import Java.lang.ref.ReferenceQueue;
public class Main {public
static void Main (string[] args) {
referencequeue<string> queue = new Referenceque Ue<string> ();
phantomreference<string> PR = new phantomreference<string> (new String ("Hello"), queue);
System.out.println (Pr.get ());
}
Two. Further understanding of soft references and weak references
For strong references, we usually use them when writing code. For the other three types of references, the most commonly used are soft and weak references, and these 2 kinds have similarities and differences. They are all used to describe non-essential objects, but objects associated with soft references are reclaimed only when there is not enough memory, and objects associated with weak references are always reclaimed when the JVM is garbage collected.
In the SoftReference class, there are three methods, two construction methods, and a Get method (Wekreference similar):
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;
}
The Get method is used to obtain a reference to the object associated with the soft reference and returns NULL if the object is reclaimed.
When using soft references and weak references, we can display a System.GC () to notify the JVM of garbage collection, but it is important to note that, although notifications are issued, the JVM does not necessarily execute immediately, meaning that the JVM must be garbage collected at this point.
Three. How to solve oom problem with soft reference and weak reference
As we talked about the basics of soft references and weak references, how do you use them to optimize program performance to avoid oom problems?
For example, if you have an application that needs to read a large number of local images, and if you read the pictures from the hard disk each time, it can severely affect performance, but if you load all of your memory and potentially cause a memory overflow, using a soft reference can solve the problem.
The design idea is: With a hashmap to save the picture path and the corresponding Picture object associated soft reference between the mapping relationship, in the memory is not enough, the JVM will automatically reclaim these cached image objects occupy space, thus effectively avoiding the oom problem. It is often used in Android development for a large number of picture downloads.
The following code is excerpted 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) {
//strong-referenced Bitmap object
Bitmap Bitmap = bitmapfactory.decodefile (path);
Soft reference Bitmap Object
softreference<bitmap> softbitmap = new softreference<bitmap> (Bitmap);
Add the object to the map so that it caches
imagecache.put (path, softbitmap);
}
Public Bitmap Getbitmapbypath (String path) {
//Bitmap object with soft reference from cache
softreference<bitmap> Softbitmap = Imagecache.get (path);
Determine if there is a soft reference if
(Softbitmap = null) {return
null;
}
Remove the Bitmap object, if the Bitmap is recycled due to insufficient memory, will get empty
Bitmap Bitmap = Softbitmap.get ();
return bitmap;
Of course, here we give the cache replacement policy to the JVM to execute, which is a relatively simple approach. A more complex cache, we can design a separate class, where the problem involves caching strategy, you can refer to a previous blog: "Cache algorithm (page replacement algorithm)-fifo, LFU, LRU"