Strong Reference 强引用
在我们的代码里,这样的引用是强引用。
StringBuffer buffer = new StringBuffer();
那么什么时候强引用太强了呢,导致它引用的对象无法被清除,最后导致内存溢出(OutOfMemoryError)。我们来看一个缓存的例子。
例子1,
public class ReferenceTest {
//private Map map = new WeakHashMap();
//Strong Reference Map
private Map map = new HashMap();
@Before
public void setup() throws IOException{
for(int i=0 ; i <10 ; i++) {
BufferedImage img = ImageIO.read(new File("D:\\Lenovo4-2.jpg"));
map.put("img"+i, img);
}
}
@Test
public void getFromMap(){
new Thread(){
public void run(){
int i = 0;
while(i<10) {
i ++;
Object o = map.get("img"+1);
System.out.println(o);
}
}
}.start();
}
}
以上的程序在vm 参数-Xmx20m时运行出现OutOfMemoryError, 但是把HashMap换成WeakMap的时候就不会出现这种情况。
出现以上这种情况的原因是,当使用强引用的时候JVM不能够回收map引用的对象。
但是WeakMap不一样,以上例子中由于map对象已经被回收,同时map里的对象都是弱引用(WeakReference), map中的对象也被回收。
Soft Reference 软引用
SoftReference的引用强度比WeakReference强一些,它不是那种要么全有,要么全无的引用。软引用的对象会不会被垃圾回收决定于JVM内存在使用情况。我们把大数据放在列表中,比如
http://www.ibm.com/developerworks/java/library/j-jtp01246/index.html
例子2,
public class SoftReferenceTest {
private List<BufferedImage> imgs;
@Before
public void setup() throws IOException {
imgs = new ArrayList<BufferedImage>();
for (int i=0; i< 10; i++) {
BufferedImage img = ImageIO.read(new File("D:\\Lenovo4-2.jpg"));
imgs.add(img);
}
}
@Test
public void getSoftReferedObject() {
for (BufferedImage img : imgs){
System.out.println(img);
}
}
}
以上的代码在VM参数为-Xmx20m的情况下出现OutOfMemoryError,但是换成以下代码就不会
public class SoftReferenceTest {
private List<SoftReference<BufferedImage>> imgs;
@Before
public void setup() throws IOException {
imgs = new ArrayList<SoftReference<BufferedImage>>();
for (int i=0; i< 10; i++) {
SoftReference<BufferedImage> img = new SoftReference<BufferedImage>(ImageIO.read(new File("D:\\Lenovo4-2.jpg")));
imgs.add(img);
}
}
@Test
public void getSoftReferedObject() {
for (SoftReference<BufferedImage> img : imgs){
System.out.println(img.get());
}
}
}
我们在用SoftReference的时候要判断引用的对象是不是空。
Weak Reference 弱引用
http://www.ibm.com/developerworks/java/library/j-jtp11225/index.html
上面的例子1 WeakHashMap是WeakReference的一个应用。
Phantomo Reference 幻影引用
幻影引用又区别与软引用和弱引用。我们甚至 不能像SoftReference或者WeakReference一样通过get方法得到被引用对象--调用get方法永远返回空。幻影引用的作用在于:第一能够通过它判断一个对象已经被垃圾回收;第二,避免重写finalize方法以复活对象时,为这些对象创建强引用。
Java区分引用(Strong,Soft,Weak,Phathom)有什么用?
让垃圾回收器更好地管理内存,防止潜在的内存泄露。
Original explanation
http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html