4.3 KiB
4.3 KiB
title, date, tags
| title | date | tags | |
|---|---|---|---|
| JVM笔记 | 2024-08-25 |
|
软引用(Soft Reference)和弱引用(Weak Reference)都是 Java 中提供的引用类型,它们的主要作用是控制垃圾回收机制如何处理引用对象。它们都属于 java.lang.ref 包中,并且在不同的场景中可以避免内存泄漏,并帮助实现更灵活的内存管理。
1. 软引用(Soft Reference)
- 定义:软引用是一种在内存充足时不会被垃圾回收器回收的引用类型,只有在内存不足时,垃圾回收器才会回收这些对象。
- 特点:
- 软引用通常用于实现内存敏感的缓存。
- 如果 JVM 运行时内存不足,软引用指向的对象会被回收。
- 软引用的对象会在垃圾回收时被清理,但如果 JVM 内存充足,它们会一直存在。
- 用途:
- 用于内存缓存,例如当内存不足时,缓存中的一些对象可以被回收,但并不在内存充足时轻易回收。
- 如何使用:
- 软引用的对象通过
SoftReference类来创建。 - 一般结合
SoftReference和SoftReference.get()来使用。
- 软引用的对象通过
import java.lang.ref.*;
public class SoftReferenceExample {
public static void main(String[] args) {
String str = new String("Hello");
SoftReference<String> softRef = new SoftReference<>(str);
// 在内存充足时,softRef.get() 可以访问对象
System.out.println(softRef.get()); // 输出:Hello
str = null; // 将原始引用设为 null
// 如果 JVM 内存不足,softRef.get() 可能返回 null
System.gc(); // 触发垃圾回收
System.out.println(softRef.get()); // 输出:null (如果对象被回收)
}
}
2. 弱引用(Weak Reference)
- 定义:弱引用是一种比软引用更弱的引用类型。弱引用指向的对象,在垃圾回收时只要没有强引用指向它,就会被回收。
- 特点:
- 弱引用的对象会在下一次垃圾回收时被回收,无论内存是否充足。
- 弱引用常用于实现那些不阻止对象回收的场景,如在某些缓存机制中,用来缓存不需要强引用的对象。
- 用途:
- 用于对象的缓存或者在一些不需要长期存在的资源管理中。
- 典型的应用是
**ThreadLocal**类,它使用弱引用来存储每个线程的局部变量。
- 如何使用:
- 使用
WeakReference类创建弱引用对象。 - 和软引用一样,通过
WeakReference.get()方法来获取对象。
- 使用
import java.lang.ref.*;
public class WeakReferenceExample {
public static void main(String[] args) {
String str = new String("Hello");
WeakReference<String> weakRef = new WeakReference<>(str);
// 在没有强引用时,weakRef.get() 会返回 null
System.out.println(weakRef.get()); // 输出:Hello
str = null; // 将原始引用设为 null
System.gc(); // 强制触发垃圾回收
System.out.println(weakRef.get()); // 输出:null (对象被回收)
}
}
3. 软引用与弱引用的区别
| 特性 | 软引用(Soft Reference) | 弱引用(Weak Reference) |
| 回收时机 | 仅在内存不足时被回收 | 一旦没有强引用指向,立刻被垃圾回收 |
| 内存敏感性 | 相对更灵活,在内存充足时保持对象存在 | 对象更容易被回收,几乎没有内存保护 |
| 使用场景 | 实现内存敏感缓存,如图片缓存、对象缓存 | 适用于短期存活的数据,例如 ThreadLocal |
| 对象存活周期 | 在内存充足时,可能会长时间存在 | 对象几乎总是在短时间内被回收 |
4. 总结
- 软引用:在内存不足时会被回收,适用于内存敏感的缓存场景。
- 弱引用:一旦没有强引用指向的对象就会被垃圾回收器回收,适用于短期有效的对象,如线程局部存储(
ThreadLocal)等。
两者都可以帮助实现内存管理,但选择哪个取决于你的实际需求。如果你希望缓存数据可以在内存充足时长时间保持,但在内存紧张时及时回收,可以使用软引用;如果对象不需要长期保存且希望快速回收,应该选择弱引用。
