您的位置:首页 > 编程语言 > Java开发

Java中的四大引用(强引用,弱引用,软引用,虚引用)

2017-05-09 11:22 148 查看
引用这个概念经常被提及,今天总结一下。

强引用

强引用即(StrongReference)我们最常使用的引用,A a=new A()。这个a就是一个强引用。



软引用

即(SoftReference),



Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;
sf.get();//有时候会返回null


弱引用

即(WeakReference



Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;
wf.get();//有时候会返回null
wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾

虚引用

即(PhantomReference



Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj=null;
pf.get();//永远返回null
pf.isEnQueued();//返回是否从内存中已经删除


引用的作用

强引用就不说了,大家都知道。软引用一般可以用来做缓存,比如一个很大的对象,我们重新加载比较耗时间,用强引用又可能内存溢出,就用软引用咯。

弱引用的典型引用就是WeakHashMap,有时候我们想要JVM快速回收某个对象时,就用弱引用。

下面来个例子:

package weakmap;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class ThreadGC implements Runnable {

private WeakReference<byte[]> k;
private ReferenceQueue referenceQueue;
public void setReferenceQueue(ReferenceQueue referenceQueue) {
this.referenceQueue=referenceQueue;
}

@Override
public void run() {
// TODO Auto-generated method stub
int cnt = 0;
try {
while((k = (WeakReference) referenceQueue.remove()) != null) {
System.out.println((cnt++) + "回收了:" + k);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
package weakmap;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class Client {

public static void main(String[] args) {
// TODO Auto-generated method stub
Object value = new Object();
Map<Object, Object> map = new HashMap<>();
ReferenceQueue referenceQueue=new ReferenceQueue<>();
ThreadGC threadGC=new ThreadGC();
threadGC.setReferenceQueue(referenceQueue);

new Thread(threadGC).start();

for(int i = 0;i < 10000;i++) {
byte[] bytes = new byte[1024*1024];
WeakReference<byte[]> weakReference = new WeakReference<byte[]>(bytes, referenceQueue);
map.put(weakReference, value);
}
System.out.println("map.size->" + map.size());
}

}
WeakHashMap应该也是类似的实现,把HashMap的key用弱引用,可以实现快速内存回收。

虚引用

下面来个例子:

package weakmap;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Field;

public class Test {
public static boolean isRun = true;

@SuppressWarnings("static-access")
public static void main(String[] args) throws Exception {
String abc = new String("abc");
System.out.println(abc.getClass() + "@" + abc.hashCode());
final ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();

new Thread() {
public void run() {
while (isRun) {
Object obj = referenceQueue.poll();  //引用队列里有对象
if (obj != null) {
try {
Field rereferent = Reference.class
.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(obj);
System.out.println("gc will collect:"
+ result.getClass() + "@"
+ result.hashCode() + "\t"
+ (String) result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}.start();

PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,
referenceQueue);
abc = null;
Thread.currentThread().sleep(3000);
System.gc();
Thread.currentThread().sleep(3000);
isRun = false;
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息