How Java effectively avoids oom: good at using soft and weak references
Presumably many friends will not be unfamiliar with the error of Oom (OutOfMemory), and when encountering this kind of mistake how to solve this problem effectively? Today, let's take a look at how to use soft and weak references to effectively solve the oom problem in your program. The following is the directory outline for this article:
I. Understanding the concept of strong references, soft references, weak references, and virtual references
Two. Further understanding of soft and weak references
Three. How to solve oom problems with soft and weak references
If there are any mistakes, I would appreciate your understanding and criticism.
Please respect the author's labor results, reproduced please indicate the original link:
Http://www.cnblogs.com/dolphin0520/p/3784171.html
I. Understanding the concept of strong references, soft references, weak references, and virtual references
In Java, although it is not necessary for programmers to manually manage the life cycle of objects, it is necessary to use soft and weak references if you want certain objects to have a certain life cycle (for example, the JVM will automatically reclaim some objects to avoid outofmemory errors when memory is low).
Starting with Java SE2, there are four types of references: Strong references, soft references, weak references, and virtual references. These four reference types are available in Java for two purposes: the first is to allow programmers to determine the life cycle of certain objects through code, and the second is to facilitate garbage collection by the JVM. Here's a look at the concepts of these four types of references:
1. Strong references (strongreference)
Strong references are commonly found in program code, such as the following code in which both object and Str are strong references:
12 |
Object object = new Object(); String str = "hello" ; |
As long as an object has a strong reference associated with it, the JVM must not reclaim the object, even if the JVM prefers to throw a outofmemory error in case of low memory. For example, the following code:
12345678910 |
public class Main {
public static void main(String[] args) {
new Main().fun1();
}
public void fun1() {
Object object =
new Object();
Object[] objArr =
new Object[
1000
];
}
}
|
When running to object[] Objarr = new object[1000]; when there is not enough memory, the JVM throws an oom error and does not reclaim the object pointed to by object. Note, however, that when Fun1 runs out, both object and Objarr are no longer present, so the objects they point to will be reclaimed by the JVM.
If you want to break the association between a strong reference and an object, you can display the reference assignment to NULL, so that the JVM reclaims the object at the appropriate time.
For example, in the clear method of the vector class, the cleanup is done 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 is removed from the Vector. * *@throwsArrayIndexOutOfBoundsException if the index is out of range * ({@codeIndex < 0 | | Index >= size ()}) *@paramIndex the index of the element to be removed *@returnelement that was removed *@since1.2*/PublicSynchronized E Remove (Int index) {Modcount++if (Index >= Elementcount) throw new ArrayIndexOutOfBoundsException (index); Object oldValue = Elementdata[index]; int nummoved = Elementcount-index-1; if (nummoved > 0 Elementdata, index, nummoved); Elementdata[--elementcount] = null; // Let GC do it work return< Span style= "COLOR: #000000" > (E) OldValue; }
2. Soft Reference (SoftReference)
Soft references are used to describe some useful but not necessary objects, which are represented in Java by the Java.lang.ref.SoftReference class. For objects associated with soft references, the JVM reclaims the object only when there is insufficient memory. Therefore, this is a good way to solve the problem of oom, and this feature is well suited for caching: such as Web caching, image caching, and so on.
A soft reference can be used in conjunction with a reference queue (Referencequeue), and if the object referenced by the soft reference is reclaimed by the JVM, the soft reference is added to the reference queue associated with it. The following is an example of use:
123456789 |
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 references (WeakReference)
Weak references are also used to describe non-essential objects, and when the JVM is garbage collected, the objects associated with the weak references are reclaimed regardless of the adequacy of the memory. In Java, it is represented by the Java.lang.ref.WeakReference class. The following are examples of use:
123456789101112 |
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();
//通知JVM的gc进行垃圾回收
System.out.println(sr.get());
}
}
|
The output is:
View Code
The second output is null, which means that the objects associated with the weak reference must be reclaimed as long as the JVM is garbage collected. It is important to note, however, that the object referred to by the weak reference is associated with only a weak reference, and if there is a strong reference associated with it, the object will not be reclaimed when it is garbage collected (as is the case with soft references).
A weak reference can be used in conjunction with a reference queue (Referencequeue), and if the object referenced by the weak reference is reclaimed by the JVM, the soft reference is added to the reference queue associated with it.
4. Virtual references (phantomreference)
A virtual reference differs from the previous soft reference and weak reference, and it does not affect the life cycle of the object. Represented in Java with the Java.lang.ref.PhantomReference class. If an object is associated with a virtual reference, it can be reclaimed by the garbage collector at any time, as with no reference to it.
Note that a virtual reference must be used in association with a reference queue, and when the garbage collector is ready to reclaim an object, if it finds a virtual reference, it adds the virtual reference to the reference queue associated with it. The program can see if the referenced object is going to be garbage collected by judging whether the reference queue has been added to the virtual reference. If the program discovers 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.
1234567891011 |
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());
}
}
|
Two. Further understanding of soft and weak references
For strong references, we usually use them when writing code. And for the other three types of references, the most used is soft and weak references, these 2 kinds of similarities and differences. They are all used to describe non-essential objects, but objects associated with soft references are recycled only when they are out of memory, and objects associated with weak references are always recycled when the JVM is garbage collected.
In the SoftReference class, there are three methods, two construction methods, and a Get method (similar to wekreference):
Two methods of construction:
123456789 |
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 recycled.
When using soft references and weak references, we can display the System.GC () to notify the JVM of garbage collection, but note that, although a notification is issued, the JVM does not necessarily execute immediately, which means that the JVM is not guaranteed to be garbage collected at this time.
Three. How to solve oom problems with soft and weak references
The basics of soft and weak references are described earlier, so how can you use them to optimize program performance to avoid oom problems?
As an example, if there is an application that needs to read a large number of local images, it can seriously affect performance if the images are read from the hard disk every time, but if they are all loaded into memory and can cause memory overflow, a soft reference is used to solve the problem.
The design idea is: With a hashmap to save the path of the picture and the corresponding picture object associated with the mapping between the soft reference, when the memory is low, the JVM will automatically reclaim the space occupied by these cached picture objects, thus effectively avoiding the problem of oom. It is often used in Android development for a large number of image downloads.
The following code is excerpted from the blog:
http://blog.csdn.net/arui319/article/details/8489451
12345678910111213141516171819202122232425262728293031323334353637383940 |
.....
private Map<String, SoftReference<Bitmap>> imageCache =
new HashMap<String, SoftReference<Bitmap>>();
<br>....
public void addBitmapToCache(String path) {
// 强引用的Bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(path);
// 软引用的Bitmap对象
SoftReference<Bitmap> softBitmap =
new SoftReference<Bitmap>(bitmap);
// 添加该对象到Map中使其缓存
imageCache.put(path, softBitmap);
}
public Bitmap getBitmapByPath(String path) {
// 从缓存中取软引用的Bitmap对象
SoftReference<Bitmap> softBitmap = imageCache.get(path);
// 判断是否存在软引用
if (softBitmap ==
null
) {
return null
;
}
// 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空
Bitmap bitmap = softBitmap.get();
return bitmap;
}
|
Of course, here we give the cache substitution policy to the JVM to execute, this is a relatively simple processing method. A bit more complex cache, we can design a separate class, where the problem is related to the cache policy, the specific can refer to a previous blog post: "Cache algorithm (page replacement algorithm)-fifo, LFU, LRU"
Resources:
"In-depth understanding of JVM virtual machines"
http://blog.csdn.net/arui319/article/details/8489451
http://blog.csdn.net/zsuguangh/article/details/6429592
Http://mobile.51cto.com/abased-406998.htm
How Java effectively avoids oom: good at using soft and weak references