Java的四大引用,大家都很熟悉吧:
- 强应用:正常代码中的引用。一个对象能通过强应用访问到,那它就永远不会被回收
- 软引用:比强引用弱一级的引用,内存不足时引用指向的对象会被回收
- 弱引用:比软引用弱一级的引用,下一次GC时指向对象会被回收
- 虚引用
最后一个虚应用是今天要讨论的。很多文章都是这么写的:
一个对象是否有虚引用存在,对其生存不会产生任何影响。
事实上,这个是错的。正确的表述是:
在Java 8以及之前的版本中,在虚引用回收后,虚引用指向的对象才会回收。在Java 9以及更新的版本中,虚引用不会对对象的生存产生任何影响。
一个示例
首先用Java 8,带上-Xmx10m -XX:+HeapDumpOnOutOfMemoryError
参数运行如下代码:
Main.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue;
public final class Main {
public static void main(String[] args) throws InterruptedException { ReferenceQueue<byte[]> queue = new ReferenceQueue<>(); PhantomReference<byte[]> ref = new PhantomReference<>(new byte[1024 * 1024 * 5], queue);
System.out.println(queue.poll()); System.out.println("第一次gc"); System.gc(); Thread.sleep(300L); System.out.println(queue.poll()); System.out.println("第二次gc"); System.gc(); byte[] bytes1 = new byte[1024 * 1024 * 6]; System.out.println("ending"); } }
|
你猜猜结果是什么?