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; // 可以释放强引用