Java中的软引用、弱引用 通俗举例实战详解

在Java中,软引用(SoftReference)和弱引用(WeakReference)是两种特殊的引用类型,它们主要用于优化内存管理和垃圾回收过程。

软引用(SoftReference)

软引用主要用于实现内存敏感的高速缓存。在JVM内存不足时,软引用指向的对象会被回收,如果回收后内存仍然不足,才会抛出OutOfMemoryError。软引用可以与引用队列(ReferenceQueue)联合使用,以便在对象被回收时得到通知。

例子及代码示例

import java.lang.ref.ReferenceQueue;  
import java.lang.ref.SoftReference;  
  
public class SoftReferenceExample {  
    public static void main(String[] args) {  
        // 创建一个引用队列  
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();  
  
        // 创建一个400MB的字节数组,并用软引用包装  
        byte[] data = new byte[1024 * 1024 * 400]; // 假设堆内存足够大  
        SoftReference<byte[]> softRef = new SoftReference<>(data, queue);  
  
        // 去掉对原始数据的强引用  
        data = null;  
  
        // 模拟内存不足(实际情况下由JVM决定)  
        // 假设此时JVM决定回收软引用指向的对象  
  
        // 尝试从软引用中获取对象  
        byte[] retrievedData = softRef.get();  
        if (retrievedData != null) {  
            System.out.println("数据成功从软引用中获取");  
        } else {  
            System.out.println("数据已被回收");  
        }  
  
        // 清理softReference对象(如果必要)  
        // 通过引用队列来清理失去引用的SoftReference对象  
        SoftReference<byte[]> ref;  
        while ((ref = (SoftReference<byte[]>) queue.poll()) != null) {  
            // 可以在这里进行清理操作  
            System.out.println("清理了一个软引用对象");  
        }  
    }  
}

注意:由于JVM的内存管理策略,上述代码中的“模拟内存不足”部分在实际运行时并不会直接触发,而是由JVM的垃圾回收器根据内存使用情况自动决定。

弱引用(WeakReference)

弱引用比软引用更弱一些,它只能存活到下一次垃圾回收发生之前。无论当前内存空间是否足够,只要发生垃圾回收,弱引用指向的对象就会被回收。弱引用同样可以与引用队列联合使用。

例子及代码示例

import java.lang.ref.ReferenceQueue;  
import java.lang.ref.WeakReference;  
  
public class WeakReferenceExample {  
    public static void main(String[] args) {  
        // 创建一个引用队列  
        ReferenceQueue<Object> queue = new ReferenceQueue<>();  
  
        // 创建一个对象,并用弱引用包装  
        Object obj = new Object();  
        WeakReference<Object> weakRef = new WeakReference<>(obj, queue);  
  
        // 去掉对原始对象的强引用  
        obj = null;  
  
        // 触发垃圾回收(实际运行时可能由JVM自动触发)  
        System.gc();  
  
        // 尝试从弱引用中获取对象  
        Object retrievedObj = weakRef.get();  
        if (retrievedObj != null) {  
            System.out.println("对象成功从弱引用中获取");  
        } else {  
            System.out.println("对象已被回收");  
        }  
  
        // 清理weakReference对象(如果必要)  
        // 通过引用队列来清理失去引用的WeakReference对象  
        WeakReference<Object> ref;  
        while ((ref = (WeakReference<Object>) queue.poll()) != null) {  
            // 可以在这里进行清理操作  
            System.out.println("清理了一个弱引用对象");  
        }  
    }  
}

在上面的弱引用示例中,即使堆内存充足,一旦垃圾回收发生,弱引用指向的对象也可能被回收。这使得弱引用非常适合用于实现那些非必需的对象缓存,比如ThreadLocal中的key等。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值