WeakReference
0. 类A
A是一个类,此时有一个类B想要使用A中的方法
public class A {
int id;
int age;
public A(int id, int age) {
this.id = id;
this.age = age;
}
public String printString() {
return "ID:" + id +"; " + "AGE:" + age;
}
}
1. 强引用
public class StrongReferenceDemo {
private A a;
public StrongReferenceDemo(A a) {
this.a = a;
}
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
A a = new A(10, 10);
StrongReferenceDemo demo = new StrongReferenceDemo(a);
// 通过强引用调用A的方法
System.out.println("持有的A的引用:" + demo.a);
System.out.println("调用A中的方法: " + demo.a.printString());
// 此时原来的对象A因为种种原因,比如Android中的Activity奔溃了
a = null;
//Handler如果持有的是强引用的话,当GC的时候,Activity对象A不能被回收,因为StrongReferenceDemo还持有指向它的引用,可达性算法分析对象A还可达
System.gc();
Thread.sleep(3000);
System.out.println("GC后持有的A的引用:" + demo.a);
System.out.println("调用A中的方法: " + demo.a.printString());
}
}
输出:
2. 弱引用(WeakReference)
当垃圾回收器扫描到只具有弱引用的对象,不管当前内存空间是否足够,都会回收该对象
public class WeakReferenceDemo {
private Reference<A> a;
private ReferenceQueue<A> queue;
public WeakReferenceDemo(A a) {
queue = new ReferenceQueue<>();
this.a = new WeakReference<A>(a, queue);
}
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
A a = new A(10, 10);
WeakReferenceDemo demo = new WeakReferenceDemo(a);
// 通过弱引用调用A的方法
System.out.println("持有的A的引用:" + demo.a.get());
System.out.println("调用A中的方法: " + demo.a.get().printString());
// 此时原来的对象A因为种种原因,比如Android中的Activity奔溃了
a = null;
// Handler如果持有的是强引用的话,当GC的时候,Activity对象A不能被回收,因为可达性算法分析对象A还可达
// 但是现在Handler持有的是弱引用,所以当GC的时候,对象A可以被回收
System.gc();
// 那么如何在当前类中去判断A已经被回收了呢
// 这就是ReferenceQueue的作用了,当弱引用的对象被回收了,JVM会把指向它的弱引用放入到关联的引用队列中去
Thread.sleep(3000);
Reference<? extends A> a2 = demo.queue.poll();
System.out.println("GC后持有的A的引用:" + demo.a.get());
System.out.println("引用队列中的元素:" + a2);
if (a2 != null) {
System.out.println("对象A已经被回收!!!");
}
}
}
输出:
使用场景:
- 比如Android开发中常用的Handler,为防止内存泄露,使用静态内部类来实例化Handler,同时为了在Handler中调用Activity的组件方法,所以使用弱引用指向Activity对象。
3. 软引用(SoftReference)
如果一个对象只具有软引用,在内存足够时,垃圾回收器不会回收它;如果内存不足,就会回收这个对象。
使用场景:
- 图片缓存。图片缓存框架中,“内存缓存”中的图片是以这种引用保存,使得 JVM 在发生 OOM 之前,可以回收这部分缓存。
- 网页缓存。