1.强引用(StrongReference)
2.软引用(SoftReference)
3.弱引用(WeakReference)
4.虚引用(PhantomReference)
5.案例:
从高到低高到低分别为:强引用、软引用、弱引用和虚引用
1.强引用(StrongReference)
我们使用的引用大多是强引用,这是最常用的引用。如果一个对象有
强引用类似于必不可少 垃圾回收器永远不会回收少的日用品。当内存空间不足时,Java
虚
拟机宁愿抛出 OutOfMemoryError 使程序错误 异常终止不会随意回收强引用对象
解决内存不足的问题。
2.软引用(SoftReference)
如果内存空间足够,垃圾回收器就不会回收。如果内存空间不足,它将被回收
大象的内存。只要垃圾回收器 程序可以使用对象而不回收。
3.弱引用(WeakReference)
扫描垃圾回收器线程 在管辖内存区域的过程中,一旦发现只有弱引用对象, 不管当
前内存空间足够 它的内存是否会被回收。但是,由于垃圾回收器是一个优先级很低的线程, 因
此不一定 很快就会发现只有弱者 引用对象。 弱引用和引用队列(ReferenceQueue)联
如果引用弱引用弱引用 对象被垃圾回收,Java
虚拟机将添加这个弱引用与之相关
引用队列。
4.虚引用(PhantomReference)
如果一个对象只持有虚假引用,它可能在任何时候都会被垃圾,就像没有引用一样 回收。虚
引用主要用于跟踪 跟踪对象的垃圾回收活动。虚引用与软引用与弱引用的区别在于,虚引用必须是
须和引用队 列(ReferenceQueue)
联合 使用。当垃 当垃圾回收器准备回收一个物体时,如果发现它仍然存在
虚假引用将在回收对象内 存之前,加上这个虚引 进入与之相关的引用队列。程序可以通过
引用队列中有过判断 是否加入了虚引用,来了 被引用的对象是否会被解决 垃圾回收。如果程序。
如果发现一个虚拟引用已经加入引用队列,则可以在引用对象中 回收前必须采用内存 要
的行动。
public class Demo1 { public static void main(String[] args) { ///这是强引用 String str = "hello"; //现在我们通过以上强引用创建软引用,所以现在 str 有两个引用指向它 SoftReference<String> soft = new SoftReference<String>(str); str = null; //可用 get()引用指向对象 System.out.println(soft.get();//输出 hello } }
public class Demo2 { public static void main(String[] args) { ///这是强引用 String str="hello"; ReferenceQueue<? super String> q=new ReferenceQueue<String>(); //现在我们通过上面的强引用创造了一个虚引用,所以现在 str 有两个引用指向它 PhantomReference<String> p=new PhantomReference<String>(str, q); //可用 get()引用指向对象 System.out.println(q.poll();//输出 null } }
下面再看一个,先创建一个
Store
类,内部定义一个大的数组,目的是创建对象,
为了提高回收的可能性,获得更多的内存!
public class Store {
public static final int SIZE = 10000;
private double[] arr = new double[SIZE];
private String id;
public Store() {
}
public Store(String id) {
super();
this.id = id;
}
@Override
protected void finalize() throws Throwable {
System.out.println(id + "被回收了");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return id;
}
}
依次创建软引用,弱引用,虚引用个
10
个!
public class Demo3 {
public static ReferenceQueue<Store> queue = new ReferenceQueue<Store>();
public static void checkQueue() {
if (queue != null) {
@SuppressWarnings("unchecked")
Reference<Store> ref = (Reference<Store>) queue.poll();
if (ref != null)
System.out.println(ref + "......" + ref.get());
}
}
public static void main(String[] args) {
HashSet<SoftReference<Store>> hs1 = new HashSet<SoftReference<Store>>();
HashSet<WeakReference<Store>> hs2 = new HashSet<WeakReference<Store>>();
//创建 10 个软引用
for (int i = 1; i <= 10; i++) {
SoftReference<Store> soft = new SoftReference<Store>(new
Store("soft" + i), queue);
System.out.println("create soft" + soft.get());
hs1.add(soft);
}
System.gc();
checkQueue();
//创建 10 个弱引用
for (int i = 1; i <= 10; i++) {
WeakReference<Store> weak = new WeakReference<Store>(new
Store("weak" + i), queue);
System.out.println("create weak" + weak.get());
hs2.add(weak);
}
System.gc();
checkQueue();
//创建 10 个虚引用
HashSet<PhantomReference<Store>> hs3 = new
HashSet<PhantomReference<Store>>();
for (int i = 1; i <= 10; i++) {
PhantomReference<Store> phantom = new PhantomReference<Store>(new
Store("phantom" + i), queue);
System.out.println("create phantom " + phantom.get());
hs3.add(phantom);
}
System.gc();
checkQueue();
}
}
程序执行结果:

可以看到虚引用和弱引用被回收掉。。。