强软弱虚,你真的懂java中的引用吗?

强软弱虚,Java中常见的四种引用。


1.强引用

强引用(Strong Reference)是最常见的引用类型,在Java中使用最广泛。

当我们使用一个对象的强引用时,JVM会确保该对象不会被垃圾回收器回收,只有当强引用被显式地释放(赋值为null)或不再被使用时,垃圾回收器才会回收该对象。

强引用的特点如下:

  1. 强引用可以直接访问对象并保持对其的引用关系,对象不会被回收。
  2. 强引用可以作为对象的唯一引用,当没有任何强引用指向一个对象时,该对象就变成了可回收的垃圾。
  3. 强引用可以通过赋值为null来释放对对象的引用,使得对象变为垃圾,等待下一次垃圾回收。

示例代码如下:

public class StrongReferenceExample {
    public static void main(String[] args) {
        // 创建一个字符串对象并创建强引用
        String data = "Hello World";
        
        // 输出强引用对象的值
        System.out.println("Strong reference value: " + data);
        
        // 释放强引用
        data = null;
        
        // 再次输出强引用对象的值(此时为null)
        System.out.println("Strong reference value after release: " + data);
        
        // 手动触发垃圾回收
        System.gc();
    }
}

强软弱虚,你真的懂java中的引用吗?_第1张图片

在上述代码中,我们创建了一个字符串对象,并使用强引用对其进行引用。

在释放强引用后,对象变为可回收的垃圾。

通过手动触发垃圾回收,可以看到输出结果中没有任何与强引用对象相关的信息。

这说明强引用不会被垃圾回收器回收,只有当没有任何强引用指向对象时,对象才会被回收。

2.软引用

软引用(Soft Reference)是Java中一种相对较弱的引用类型。

与强引用不同,当内存不足时,垃圾回收器可能会回收被软引用关联的对象,但不保证一定回收。

软引用通常用于实现内存敏感的高速缓存或对象缓存等场景,当系统内存不足时,可以优先回收这部分对象,以释放内存空间。

软引用的特点如下:

  1. 软引用可以访问对象并保持对其的引用关系,但允许被垃圾回收器回收。
  2. 当内存不足时,垃圾回收器可能会回收被软引用关联的对象,以释放内存空间。
  3. 软引用适合用于实现内存敏感的高速缓存或对象缓存等场景,可以在内存紧张时回收一部分对象,避免内存溢出。

代码如下:

import java.lang.ref.SoftReference;

public class SoftReferenceExample {
    public static void main(String[] args) {
        // 创建一个字符串对象并创建软引用
        SoftReference<String> softRef = new SoftReference<>("Hello World");
        
        // 从软引用中获取对象
        String data = softRef.get();
        
        // 输出软引用对象的值
        System.out.println("Soft reference value: " + data);
        
        // 释放软引用
        softRef.clear();
        
        // 再次从软引用中获取对象(此时为null)
        data = softRef.get();
        
        // 输出软引用对象的值(此时为null)
        System.out.println("Soft reference value after release: " + data);
        
        // 手动触发垃圾回收
        System.gc();
    }
}

强软弱虚,你真的懂java中的引用吗?_第2张图片

在上述代码中,我们创建了一个字符串对象,并使用软引用对其进行引用。

在释放软引用后,对象变为可回收的垃圾。

通过手动触发垃圾回收,可以看到输出结果中没有任何与软引用对象相关的信息。

这说明软引用可以被垃圾回收器回收,但不是一定会回收,它的回收行为取决于内存的使用情况。

3. 弱引用

弱引用(Weak Reference)是Java中一种比软引用更弱的引用类型。

与软引用不同,弱引用在垃圾回收时更容易被回收。

当垃圾回收器扫描到只有弱引用关联的对象时,无论内存是否充足,都会立即回收该对象。

弱引用的特点如下:

  1. 弱引用可以访问对象并保持对其的引用关系,但在垃圾回收时更容易被回收。
  2. 当垃圾回收器扫描到只有弱引用关联的对象时,无论内存是否充足,都会立即回收该对象。
  3. 弱引用通常用于实现对象缓存,当对象不再被强引用引用时,可以立即回收,避免内存溢出。

示例代码如下:

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        // 创建一个字符串对象并创建弱引用
        WeakReference<String> weakRef = new WeakReference<>("Hello World");
        
        // 从弱引用中获取对象
        String data = weakRef.get();
        
        // 输出弱引用对象的值
        System.out.println("Weak reference value: " + data);
        
        // 释放弱引用
        weakRef.clear();
        
        // 再次从弱引用中获取对象(此时为null)
        data = weakRef.get();
        
        // 输出弱引用对象的值(此时为null)
        System.out.println("Weak reference value after release: " + data);
        
        // 手动触发垃圾回收
        System.gc();
    }
}

强软弱虚,你真的懂java中的引用吗?_第3张图片

在上述代码中,我们创建了一个字符串对象,并使用弱引用对其进行引用。

在释放弱引用后,对象变为可回收的垃圾。

通过手动触发垃圾回收,可以看到输出结果中没有任何与弱引用对象相关的信息。

这说明弱引用在垃圾回收时更容易被回收,即使内存充足,垃圾回收器也会立即回收弱引用关联的对象。

4.虚引用

虚引用(Phantom Reference)是Java中最弱的引用类型,也是最少被使用的一种引用类型。

与弱引用和软引用不同,虚引用的存在几乎没有实际意义,其主要作用是在对象被回收时收到一个系统通知。

虚引用的特点如下:

  1. 虚引用不能通过get()方法获取引用的对象,而且始终返回null。
  2. 虚引用主要用于跟踪对象被垃圾回收的状态,当对象即将被回收时,虚引用会收到一个系统通知。
  3. 虚引用必须和引用队列(ReferenceQueue)一起使用,用于接收对象被回收的通知。

由于虚引用并不直接与对象关联,所以无法通过虚引用来获取对象的引用或访问对象的属性或方法。

它的主要作用是在对象被回收之前接收到一个通知,可以在对象被回收时进行一些必要的清理操作或记录日志等操作。

示例代码如下:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class PhantomReferenceExample {
    public static void main(String[] args) {
        Object referent = new Object();
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        PhantomReference<Object> phantomRef = new PhantomReference<>(referent, queue);
        
        // 输出虚引用对象
        System.out.println("Phantom reference: " + phantomRef);
        
        // 从引用队列中获取已被回收的虚引用
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(new Object(), referenceQueue);
        
        // 输出虚引用对象
        System.out.println("Phantom reference from reference queue: " + referenceQueue.poll());
        
        // 手动触发垃圾回收
        System.gc();
        
        // 从引用队列中获取已被回收的虚引用
        System.out.println("Phantom reference from reference queue: " + referenceQueue.poll());
    }
}

强软弱虚,你真的懂java中的引用吗?_第4张图片

在上述代码中,我们创建了一个虚引用对象并输出了该引用对象的信息。

然后,我们手动触发了垃圾回收,并尝试从引用队列中获取已被回收的虚引用对象。

可以看到,虚引用在输出结果中始终为null,说明无法通过虚引用获取对象或引用的信息。

同时,从引用队列中获取的虚引用对象也为null,说明虚引用被回收时会被放入引用队列中。

5.总结

通过上述4个例子和代码,应该对这4个概念掌握了。

这下就算面试官在问,也能手撕面试官了。

ok,我已讲完。

你可能感兴趣的:(Java面试题,java,jvm,开发语言)