package com.xxl.job.admin.mytest;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ReferenceDemo {
@Override
protected void finalize() {
System.out.println("触发 gc 通知垃圾回收...");
}
public static void main(String[] args) {
ReferenceQueue<ReferenceDemo> referenceQueue = new ReferenceQueue<>();
PhantomReference<ReferenceDemo> reference = new PhantomReference<>(new ReferenceDemo(), referenceQueue);
List<byte[]> list = new ArrayList<>();
new Thread(()->{
while(true) {
list.add(new byte[1*1024*1024]);
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(reference.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()->{
while(true) {
Reference<? extends ReferenceDemo> poll = referenceQueue.poll();
// 当这个虚引用的对象被干掉了,就会放进虚引用队列
if (poll != null) {
System.out.println("------有虚对象进入了队列");
}
}
}).start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
注意运行代码之前提前设置下堆内存大小 -Xms10m -Xmx10m
运行结果:
null
null
null
null
触发 gc 通知垃圾回收...
null
null
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at com.xxl.job.admin.mytest.ReferenceDemo.lambda$main$0(ReferenceDemo.java:25)
at com.xxl.job.admin.mytest.ReferenceDemo$$Lambda$1/517380410.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
------有虚对象进入了队列
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
虚引用只是为了能够在这个对象被回收之前通知下 JVM 一声,然后再把这个对象丢进虚引用关联的队列中,等待被安排。触发 gc 通知垃圾回收...
输出结果表示这个虚引用对象被回收,------有虚对象进入了队列
输出结果表示将虚引用对象放入虚引用队列中。