强引用、软引用、弱引用、虚引用区别

1、强引用

强引用是最常见的引用类型,如果一个对象具有强引用,那么在内存不足时也不会被回收。

即使抛出 OutOfMemoryError 异常,也不会回收具有强引用的对象。

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

2、软引用

软引用在内存不足时会被垃圾回收器回收。当系统内存不足时,JVM会尝试回收软引用对象来释放一些内存。这使得软引用非常适合用来实现缓存。

import java.lang.ref.SoftReference;

Object obj = new Object();
SoftReference<Object> softRef = new SoftReference<>(obj);
obj = null; // 可以释放强引用

 使用场景举例:图片缓存

在Android开发中,图片加载和缓存是常见的需求。软引用可以用于缓存图片对象,当内存不足时,可以释放这些缓存的图片对象。在这个示例中,ImageCache 类用于缓存图片对象。addBitmapToCache 方法用于将图片放入缓存中,getBitmapFromCache 方法用于从缓存中获取图片。使用软引用来缓存图片对象,可以在系统内存不足时自动释放缓存的图片,从而避免内存溢出问题。代码如下:

import java.lang.ref.SoftReference;
import android.graphics.Bitmap;

public class ImageCache {
    private static ImageCache instance;
    private final HashMap<String, SoftReference<Bitmap>> cache;

    private ImageCache() {
        cache = new HashMap<>();
    }

    public static ImageCache getInstance() {
        if (instance == null) {
            synchronized (ImageCache.class) {
                if (instance == null) {
                    instance = new ImageCache();
                }
            }
        }
        return instance;
    }

    public void addBitmapToCache(String key, Bitmap bitmap) {
        cache.put(key, new SoftReference<>(bitmap));
    }

    public Bitmap getBitmapFromCache(String key) {
        SoftReference<Bitmap> softRef = cache.get(key);
        if (softRef != null) {
            Bitmap bitmap = softRef.get();
            if (bitmap != null) {
                return bitmap; // 返回缓存的图片
            }
        }
        return null;
    }
}

3、弱引用

弱引用同样会被垃圾回收器回收,但它的生命周期比软引用更短。当垃圾回收器运行时,只要发现了弱引用对象,无论当前内存是否充足,都会立即将其回收。

import java.lang.ref.WeakReference;

Object obj = new Object();
WeakReference<Object> weakRef = new WeakReference<>(obj);
obj = null; // 可以释放强引用

       弱引用通常用于需要跟踪对象是否被回收的场景。与软引用不同的是,弱引用指向的对象在下一次垃圾回收时就会被回收,无论内存是否充足。这使得弱引用适合用于那些可以被及时回收且不影响程序正常运行的对象。使用场景之一:对象监视器,代码如下:

import java.lang.ref.WeakReference;

public class ObjectMonitor {
    private WeakReference<Object> monitoredObject;

    public void monitor(Object obj) {
        monitoredObject = new WeakReference<>(obj);
    }

    public void checkStatus() {
        if (monitoredObject != null && monitoredObject.get() == null) {
            System.out.println("监视对象已被回收.");
        } else {
            System.out.println("监视对象依旧存活.");
        }
    }

    public static void main(String[] args) {
        ObjectMonitor monitor = new ObjectMonitor();
        
        // 监视对象
        Object obj = new Object();
        monitor.monitor(obj);
        
        // 检查对象状态
        monitor.checkStatus();

        // 模拟对象被回收
        obj = null;
        System.gc(); // 手动触发垃圾回收
        
        // 检查对象状态(此时对象应已被回收)
        monitor.checkStatus();
    }
}

  monitoredObject != null: 这部分判断主要是为了确保 monitoredObject 不为 null,如果为 null,说明这个弱引用对象已经被回收了。 monitoredObject.get() == null: 这部分判断用于检查 monitoredObject 引用的对象是否为 null。如果 get() 返回 null,表示被监视的对象已经被垃圾回收器回收了。当两个条件都满足时,就说明被监视的对象已经被垃圾回收了。

 4、虚引用

 虚引用是最弱的一种引用关系。和前三种引用不同,虚引用的对象即使存在也会被当作不存在。主要用于在对象被回收时收到系统通知,可以在对象被垃圾回收器回收时做一些特定的处理操作。

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

Object obj = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, referenceQueue);
obj = null; // 可以释放强引用

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值