【Java】java中的五种对象引用

在java中,对象引用主要分为五种类型:强引用、软引用、

弱引用、虚引用、终结期引用。

1. 强引用

最常见的引用类型,默认创建的引用都是强引用。

Object obj = new Object(); // 强引用

特点

  • 只要强引用存在,对象永远不会被回收
  • 内存不足时抛出 OutOfMemoryError
  • 使用场景:普通对象创建

回收条件

obj = null; // 显式解除引用
2.软引用
// 创建软引用
SoftReference<byte[]> softRef = new SoftReference<>(new byte[10*1024*1024]); // 10MB

特点

  • 内存充足时不会被回收
  • 内存不足时可能被回收
  • 使用场景:图片缓存、网页缓存
3.弱引用
// 创建弱引用
WeakReference<Object> weakRef = new WeakReference<>(new Object());

// 获取对象
Object obj = weakRef.get();
if (obj != null) {
    System.out.println("弱引用对象存在");
}

// 强制垃圾回收
System.gc();

// 再次检查
if (weakRef.get() == null) {
    System.out.println("对象已被回收");
}

特点

  • 下一次垃圾回收时立即回收(无其他引用)
  • 不会阻止垃圾回收
  • 使用场景:临时对象映射、监控对象状态

虚引用和终结器引用在常规开发中是不会使用的。

4.虚引用

虚引用也被称为幽灵引用或者幻影引用,它不会影响对象的生命周期,也无法通过虚引用获取到对象实例。虚引用的主要作用是在对象被垃圾回收时收到一个系统通知。创建虚引用时必须关联一个引用队列(ReferenceQueue),当虚引用引用的对象被垃圾回收后,该虚引用会被加入到关联的引用队列中。

使用场景

虚引用主要用于在对象被回收时执行一些额外的清理操作,比如管理直接内存。直接内存不受 Java 堆内存管理,需要手动释放,使用虚引用可以在对象被回收时释放对应的直接内存资源。

示例代码

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

public class PhantomReferenceExample {
    public static void main(String[] args) {
        // 创建一个对象
        Object obj = new Object();
        // 创建引用队列
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        // 创建虚引用,关联对象和引用队列
        PhantomReference<Object> phantomReference = new PhantomReference<>(obj, referenceQueue);

        // 断开强引用
        obj = null;

        // 建议 JVM 进行垃圾回收
        System.gc();

        try {
            // 等待一段时间,让垃圾回收有机会执行
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 检查引用队列中是否有虚引用
        if (referenceQueue.poll() != null) {
            System.out.println("对象已被垃圾回收,虚引用已加入引用队列");
        } else {
            System.out.println("对象尚未被垃圾回收");
        }
    }
}

特点

  • 无法通过 get() 获取对象
  • 对象被回收时收到通知
  • 使用场景:直接内存清理、资源释放
5.终结器引用
class ResourceHolder {
    private byte[] data = new byte[1024*1024]; // 1MB
    
    @Override
    protected void finalize() throws Throwable {
        try {
            System.out.println("执行 finalize() 清理资源");
        } finally {
            super.finalize();
        }
    }
}

// 使用
new ResourceHolder();
System.gc();

特点

  • 对象被回收前会调用 finalize() 方法
  • 执行时间不确定
  • 使用场景:传统资源清理(已被 try-with-resources 取代)

try-with-resources

try (
    InputStream in = new FileInputStream("input.txt");
    OutputStream out = new FileOutputStream("output.txt")
) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
    }
} // 自动关闭 in 和 out

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