强引用
执行代码
private static void strongReference() {
MyObject myObject = new MyObject();
System.out.println("gc before : " + myObject);
System.gc();
System.out.println("gc after : " + myObject);
myObject = null ;
System.out.println("myObject is null : " + myObject);
}
执行结果:强引用如果存在引用值的时候,垃圾回收器无论什么时候都不会回收这个对象
gc before : com.wzy.Demo.MyObject@3f99bd52
gc after : com.wzy.Demo.MyObject@3f99bd52
myObject is null : null
应用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存
弱引用
执行代码
SoftReference<MyObject> myObject = new SoftReference<>(new MyObject());
System.out.println("gc before : " + myObject.get());
System.gc();
TimeUnit.SECONDS.sleep(1);
System.out.println("gc after : " + myObject.get());
try {
byte[] bytes = new byte[20 * 1024 * 1024];
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("myObject is : " + myObject.get());
}
配置环境变量,内存空间设置为10M且最大内存为10M
执行结果:软引用,在内存空间足够的情况下,垃圾回收是不进行对该对象进行垃圾回收,但是如果内存不够的时候,就会对该对象进行垃圾回收。
gc before : com.wzy.Demo.MyObject@3f99bd52
gc after : com.wzy.Demo.MyObject@3f99bd52
myObject is : null
=======执行销毁对象
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.wzy.Demo.RefDemo.main(RefDemo.java:18)
软引用
执行代码
WeakReference<MyObject> myObject = new WeakReference<>(new MyObject());
System.out.println("gc before : " + myObject.get());
System.gc();
System.out.println("gc after : " + myObject.get());
执行结果:软引用,只要进行垃圾回收,引用对象就会被回收
gc before : com.wzy.Demo.MyObject@3f99bd52
gc after : null
=======执行销毁对象
应用场景:弱应用同样可用于内存敏感的缓存。
虚引用
执行代码
MyObject myObject = new MyObject();
ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue<>();
PhantomReference<MyObject> ph = new PhantomReference<>(myObject, referenceQueue);
// PhantomReference.get(),此方法总是返回null
System.out.println(ph.get());
ArrayList<byte[]> list = new ArrayList<>();
new Thread(()->{
while(true){
list.add(new byte[1 * 1024 *1024]);
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(ph.get() + "\t " + "list add ok");
}
}, "t1").start();
new Thread(() ->{
while (true){
Reference<? extends MyObject> poll = referenceQueue.poll();
if (poll != null){
System.out.println("=====有虚对象回收加入了队列");
break;
}
}
}, "t2").start();
执行结果:虚引用:如果一个对象持有虚引用,那么它就没有任何引用一样,在任何时候都可能被垃圾回收器回收,必须要和引用队列(ReferenceQueue)联合使用。
虚引用的主要作用是跟踪对象被垃圾回收的状态。仅仅是提供了一中对象被finalize以后,做的某些事情的通知机制。
null
null list add ok
=======执行销毁对象
null list add ok
null list add ok
null list add ok
null list add ok
null list add ok
null list add ok
Exception in thread "t1" java.lang.OutOfMemoryError: Java heap space
at com.wzy.Demo.RefDemo.lambda$main$0(RefDemo.java:22)
at com.wzy.Demo.RefDemo$$Lambda$1/1225358173.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
=====有虚对象回收加入了队列
进程已结束,退出代码0
应用场景:
设置虚引用关联对象的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。
可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。