介绍一下什么是强引用、软引用、弱引用、虚引用

让我用生活中的例子来解释这四种引用:

  1. 强引用(Strong Reference)- 就像你的必需品:
// 就像你非常需要的钱包,不会丢弃
public class StrongReferenceExample {
    public void strongReference() {
        // 强引用 - 你正在使用的钱包
        Object wallet = new Object();  
        // wallet变量指向对象的引用永远不会被垃圾回收器回收
        
        // 即使内存不足,也不会回收
        System.gc();  // 垃圾回收不会回收wallet对象
    }
}
  1. 软引用(Soft Reference)- 就像备用物品:
// 就像家里的备用手机,如果实在需要空间可以扔掉
public class SoftReferenceExample {
    public void softReference() {
        // 创建一个图片缓存
        SoftReference<ImageCache> imageCache = 
            new SoftReference<>(new ImageCache());
        
        // 使用缓存
        if (imageCache.get() != null) {
            // 缓存还在,可以使用
            imageCache.get().displayImage();
        } else {
            // 缓存被回收了,需要重新加载
            reloadCache();
        }
    }
}

// 实际应用:图片缓存
public class ImageCacheManager {
    private Map<String, SoftReference<Bitmap>> imageCache = 
        new HashMap<>();
    
    public void cacheImage(String url, Bitmap bitmap) {
        imageCache.put(url, new SoftReference<>(bitmap));
    }
    
    public Bitmap getImage(String url) {
        SoftReference<Bitmap> bitmapRef = imageCache.get(url);
        if (bitmapRef != null) {
            Bitmap bitmap = bitmapRef.get();
            if (bitmap != null) {
                return bitmap;
            }
            // 软引用对象被回收,从imageCache中移除
            imageCache.remove(url);
        }
        return null;
    }
}
  1. 弱引用(Weak Reference)- 就像借来的东西:
// 就像借来的书,随时可能要还
public class WeakReferenceExample {
    public void weakReference() {
        // 创建一个弱引用
        WeakReference<DataCache> dataCache = 
            new WeakReference<>(new DataCache());
            
        // 使用WeakHashMap存储数据
        WeakHashMap<Key, Data> cache = new WeakHashMap<>();
        cache.put(new Key("1"), new Data("data1"));
        
        // 一旦没有其他强引用指向Key对象
        // WeakHashMap中的对应条目就可能被回收
        System.gc();  // 可能触发回收
    }
}

// 实际应用:防止内存泄漏的监听器管理
public class ListenerManager {
    private List<WeakReference<EventListener>> listeners = 
        new ArrayList<>();
    
    public void addListener(EventListener listener) {
        listeners.add(new WeakReference<>(listener));
    }
    
    public void notifyListeners(Event event) {
        Iterator<WeakReference<EventListener>> iterator = 
            listeners.iterator();
            
        while (iterator.hasNext()) {
            WeakReference<EventListener> listenerRef = iterator.next();
            EventListener listener = listenerRef.get();
            if (listener != null) {
                listener.onEvent(event);
            } else {
                // 监听器对象已被回收,移除引用
                iterator.remove();
            }
        }
    }
}
  1. 虚引用(Phantom Reference)- 就像快递追踪:
// 就像快递的追踪单,不影响快递的派送,只用来追踪状态
public class PhantomReferenceExample {
    public void phantomReference() {
        // 创建引用队列
        ReferenceQueue<BigObject> referenceQueue = 
            new ReferenceQueue<>();
            
        // 创建虚引用
        PhantomReference<BigObject> phantomRef = 
            new PhantomReference<>(
                new BigObject(), 
                referenceQueue
            );
            
        // 检查对象是否被回收
        new Thread(() -> {
            try {
                Reference<?> reference = referenceQueue.remove();
                // 对象被回收了,执行清理操作
                System.out.println("对象被回收");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

// 实际应用:资源清理
public class ResourceTracker {
    private ReferenceQueue<Resource> queue = new ReferenceQueue<>();
    private List<PhantomReference<Resource>> references = 
        new ArrayList<>();
    
    public void track(Resource resource) {
        references.add(new PhantomReference<>(resource, queue));
    }
    
    public void cleanUp() {
        Reference<?> ref;
        while ((ref = queue.poll()) != null) {
            // 执行清理操作
            ((ResourcePhantomReference)ref).cleanup();
            references.remove(ref);
        }
    }
}

实际使用场景对比:

  1. 缓存实现:
public class CacheManager {
    // 强引用缓存 - 永不释放
    private Map<String, Object> strongCache = 
        new HashMap<>();
        
    // 软引用缓存 - 内存不足时释放
    private Map<String, SoftReference<Object>> softCache = 
        new HashMap<>();
        
    // 弱引用缓存 - 垃圾回收时释放
    private Map<String, WeakReference<Object>> weakCache = 
        new WeakHashMap<>();
    
    // 根据不同场景使用不同缓存
    public void putIntoCache(String key, Object value, CacheType type) {
        switch (type) {
            case STRONG:
                strongCache.put(key, value);
                break;
            case SOFT:
                softCache.put(key, new SoftReference<>(value));
                break;
            case WEAK:
                weakCache.put(key, new WeakReference<>(value));
                break;
        }
    }
}

使用建议:

  1. 使用强引用当:

    • 对象是必需的
    • 不希望对象被垃圾回收
  2. 使用软引用当:

    • 实现内存敏感的缓存
    • 对象可以被回收但最好保留
  3. 使用弱引用当:

    • 实现规范化映射
    • 防止内存泄漏
  4. 使用虚引用当:

    • 跟踪对象的回收
    • 需要在对象回收时执行特定操作

它们就像生活中对待不同物品的态度:

  • 强引用:必需品(钱包)
  • 软引用:备用品(备用手机)
  • 弱引用:借来的物品(图书馆的书)
  • 虚引用:追踪记录(快递单号)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值