【面试】Java中的引用类型

240 阅读3分钟

前言

从Jdk1.2版本后,对象的引用分为4种级别,目的是使程序能够灵活的控制对象的生命周期,由高到低分为强引用->软引用->弱引用->虚引用

强引用

任何一个对象的赋值操作就产生了对这个对象的强引用,Java中的引用默认就是强引用。

public static void main(String[] args) {
    Object objet = new Object();
}

当我们new了一个Object对象,并将值赋值给object,这个object就是new Object()的强引用,垃圾回收器绝对不会回收它。

重点: 我们的几乎所有对象实例都是在堆中有块内存存储的,当内存满了之后,就需要进行垃圾回收,那么那些没有被引用的对象就会被回收,反之,被引用的对象就不会被回收,除非当object = null,也就是对象没有被引用才会被回收。

软引用

如果一个对象存在软引用,如果内存空间充足,垃圾回收器不会回收它,如果内存空间不足,就会回收它。

软引用在java中有个专门的SoftReference类型,软引用的意思是只有在内存不足的情况下,被引用的对象才会被回收。

软引用:指的是一个引用别另外一个软对象所包装。

软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。

public static void main(String[] args) {
    Object obj = new Object();
    SoftReference<Object> softReference = new SoftReference<>(obj);
    obj = null;
    log.info("{}",softReference.get());
    // 触发GC回收调用
    System.gc();
    log.info("{}",softReference.get());
}

输出结果:

20:45:57.418 [main] INFO com.example.stream.test.Ctest - java.lang.Object@3ffc5af1
20:45:57.438 [main] INFO com.example.stream.test.Ctest - java.lang.Object@3ffc5af1

可以看到在内存充足的情况下,SoftReference引用的对象是不会被回收的,如果内存空间不足,就会将对象设置为null,通知垃圾回收器进行回收。

if(JVM内存不足) {
    // 将软引用中的对象引用置为null
    str = null;
    // 通知垃圾回收器进行回收
    System.gc();
}

弱引用

弱引用在java中有个专门的WeekReference类型,弱引用的意思是只要有垃圾回收器执行,不管你内存空间是否充足,被引用的对像都会被回收。

弱引用:指的是一个引用别另外一个弱对象所包装。

public static void main(String[] args) {
    Object obj = new Object();
    WeakReference<Object> weak = new WeakReference<>(obj);
    obj = null;
    log.info("{}",weak.get());
    // 触发GC回收调用
    System.gc();
    log.info("{}",weak.get());
}

输出结果:

21:00:34.261 [main] INFO com.example.stream.test.Ctest - java.lang.Object@3ffc5af1
21:00:34.285 [main] INFO com.example.stream.test.Ctest - null

GC过后,弱引用的对象被回收掉了

虚引用

PhantomReference(虚引用)的作用是跟踪垃圾回收器收集对象的活动,形同虚设,在任何时候都可能被垃圾回收器回收,在GC的过程中,如果发现有PhantomReference(虚引用),GC则会将引用放到ReferenceQueue(引用队列)中,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。