文章目录
- Java中几种不同的引用
- StrongReference(强引用)
- SoftReference(软引用)
- WeakReferenc(弱引用)
- 虚引用PhantomReference
Java中几种不同的引用
我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是很紧张,则可以抛弃这些对象。
Java中一共存在四种引用:
- StrongReference(强引用)
- SoftReferenc(软引用)
- WeakReferenc(弱引用)
- PhantomReference(虚引用)
这四种引用强度依次逐渐减弱。
StrongReference(强引用)
java中的引用默认就是强引用,任何一个对象的赋值操作就产生了对这个对象的强引用。如:Object obj = new Object(); 我们new了一个Object对象,并将其赋值给obj,这个obj就是new Object()的强引用。强引用的特性是只要有强引用存在,被引用的对象就不会被垃圾回收。
SoftReference(软引用)
软引用是用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
软引用是由java.lang.ref.SoftReference所提供的功能,意思是只有在内存不足的情况下,被引用的对象才会被回收。
SoftReference源码如下:
package java.lang.ref;public class SoftReference<T> extends Reference<T> {// 时间锁,由垃圾收集器更新。static private long clock;// 每次调用get方法都会更新该时间戳。JVM可能会在选择要清除的软引用时使用该字段,// 但这不是强制必须的。private long timestamp;// 返回对象的引用。如果该引用对象已经被程序或者垃圾收集器清除,则返回null。// 把最近一次垃圾回收时间赋值给timestamppublic T get() {T o = super.get();if (o != null && this.timestamp != clock)this.timestamp = clock;return o;}public SoftReference(T referent) {super(referent);this.timestamp = clock;}public SoftReference(T referent, ReferenceQueue<? super T> q) {super(referent, q);this.timestamp = clock;}
}
测试代码如下:
@Slf4j
public class RefernceTest {public static void main(String[] args) {SoftReference<Object> soft = new SoftReference<>(new Object());log.info("{}",soft.get());System.gc();log.info("{}",soft.get());}}
// 输出结果:
17:26:11.015 [main] INFO com.example.demo.thread.RefernceTest - java.lang.Object@68f7aae2
17:26:11.029 [main] INFO com.example.demo.thread.RefernceTest - java.lang.Object@68f7aae2
WeakReferenc(弱引用)
弱引用是由java.lang.ref.WeekReference所提供的功能,不同的是weekReference引用的对象只要垃圾回收执行,就会被回收,而不管是否内存不足。
WeekReference源码如下:
package java.lang.ref;public class WeakReference<T> extends Reference<T> {// 创建没有注册ReferenceQueue的弱引用public WeakReference(T referent) {super(referent);}// 创建注册了ReferenceQueue的弱引用public WeakReference(T referent, ReferenceQueue<? super T> q) {super(referent, q);}
}
测试代码如下:
@Slf4j
public class RefernceTest {public static void main(String[] args) {WeakReference<Object> weak = new WeakReference<>(new Object());log.info("{}",weak.get());System.gc();log.info("{}",weak.get());}
}// 输出结果如下
17:31:40.979 [main] INFO com.example.demo.thread.RefernceTest - java.lang.Object@68f7aae2
17:31:40.998 [main] INFO com.example.demo.thread.RefernceTest - null
虚引用PhantomReference
一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获得一个对象的实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收的时候收到一个系统通知。