本文仅供学习交流使用,侵权必删。
不作商业用途,转载请注明出处。
强引用
-
Object object=new Object();
java默认的声明方式就是强引用方式,强引用对象在遇到gc是不会被回收的。即使是内存不足导致OOM也不会回收强引用对象。 - 如果想帮助gc回收这类强引用对象可以将引用指向null,如
object=null;
。这样在没有被强引用指向的Object对象在下次gc就会被回收。
软引用
/*
-Xms5M -Xmx5M
*/
public static void main(String[] args) throws InterruptedException {
SoftReference<byte[]> sr = new SoftReference<>(new byte[1024 * 1024 * 2]);
System.out.println("softRef get: "+sr.get());//没有被回收
byte[] sr2 = new byte[1024 * 1024 * 2];
System.out.println("softRef get: "+sr.get());//已经被回收
System.out.println("normalRef :"+sr2);
}
- 通过SoftReference指向的对象就是软引用。
- 当一个对象只被软引用指向,当系统内存不足,下次gc就会回收。
- 软引用指向的对象比较适合充当缓存来使用
弱引用
public static void main(String[] args) throws InterruptedException {
WeakReference wr = new WeakReference<>(new Object());
System.gc();
System.out.println(wr.get());//null
}
- 只要遭遇gc就会被回收
虚引用
private static final ReferenceQueue QUEUE = new ReferenceQueue<>();
private static List lst = new LinkedList<byte[]>();
static class Garbage {
public Garbage() {}
}
public static void main(String[] args) {
PhantomReference pr = new PhantomReference<Object>(new Garbage(), QUEUE);
System.out.println("PhantomReference::get "+pr.get());
new Thread(() -> {
for (int i = 0; i < 5; i++) {
lst.add(new byte[1024 * 1024 * 1]);
}
}).start();
new Thread(() -> {
for (; ; ) {
Reference<? extends Garbage> ref;
if ((ref = QUEUE.poll()) != null) {
System.out.println("PhantomReference Garbage 被回收:" + ref);
System.out.println("PhantomReference::get "+ref.get());
}
}
}).start();
}
- 虚引用需要配合引用队列ReferenceQueue一齐使用,虚引用被回收后会被装到引用队列中,我们可以从队列中poll得知一个虚引用被回收从而做出一些相应的处理。
- 虚引用不能通过get()方法获取引用对象。
- 参考文献:https://www.cnblogs.com/mfrank/p/9837070.html