软引用(SoftReference)是Java中一种比较特殊的引用类型,如同弱引用(WeakReference)、虚引用(PhantomReference)一样,都是为了解决Java中的内存不足问题而出现的。
与弱引用相比,软引用的生命周期稍微长一些。软引用所指向的对象在内存中并不是一定存在的,但是如果内存空间足够,垃圾回收器就不会回收它所指向的对象。当JVM内存不足时,软引用指向的对象才会被垃圾回收器回收。
SoftReference类继承了Reference类,可以通过get()方法获得引用所指向的对象,当对象被回收后,该方法返回null。
使用场景:
在一些需要缓存数据的场合,可以使用软引用来缓存对象,当缓存对象过多时,jvm扫描到软引用对象时会及时回收相应的缓存对象,以获得更多内存空间。
示例一:
import java.lang.ref.SoftReference;
public class SoftReferenceTest {
public static void main(String[] args) {
// 创建一个字符串对象
String str = new String("www.baidu.com");
// 创建一个软引用,指向刚刚创建的字符串对象
SoftReference<String> sr = new SoftReference<String>(str);
// 把刚刚创建的字符串对象变成null
str = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 通过软引用获取字符串对象
System.out.println(sr.get());
}
}
输出结果:www.baidu.com
示例二:
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
public class SoftReferencesInHashMap {
public static void main(String[] args) {
Map<String, SoftReference<StringBuffer>> map = new HashMap<String, SoftReference<StringBuffer>>();
for (int i=0; i<100; i++) {
String key = Integer.toString(i);
StringBuffer value = new StringBuffer("Value_" + i);
map.put(key, new SoftReference<StringBuffer>(value));
}
for (int i=0; i<1000; i++) {
String key = Integer.toString(i % 100);
if (map.get(key) == null) {
System.out.println("Not found: " + key);
}
else {
StringBuffer string = map.get(key).get();
if (string == null) {
System.out.println("Object is null: " + key);
}
else {
System.out.println("String Buffer for " + key + ": " + string);
}
}
}
}
}
在该示例中,我们创建了一个HashMap,使用软引用将字符串对象缓存起来。然后,我们循环1000次从HashMap中获取字符串对象,直到JVM内存不足时,HashMap中的字符串对象才会被垃圾回收器回收。每次获取字符串对象时,程序判断该对象是否为null,以此判断该对象是否已被回收。如果对象不为null,则输出该对象的值。这样,我们就可以通过软引用实现对于大量数据的缓存,且不会对JVM内存造成大量的负担。