1. 定义强引用、软引用和弱引用的方式
- new出来的是强引用,比如
String str = new String(“123” );
- 弱引用:
WeakReference<String> weakRef=new WeakReference<String>(str);
其中str是引用
另外弱引用对应了一种map: WeakHashMap,它与HashMap相比前者的键是弱引用,而后者的键是强引用。下面的代码可以证明:
public class WeakHashMapDemo {
public static void main(String[] args) throws Exception {
String a = new String("a");
String b = new String("b");
Map weakmap = new WeakHashMap();
Map map = new HashMap();
map.put(a, "aaa"); //a上有String和HashMap的强引用
map.put(b, "bbb"); //b上有String和HashMap的强引用
weakmap.put(a, "aaa"); //再给a加上弱引用
weakmap.put(b, "bbb"); //再给b加上弱引用
map.remove(a); //撤销a上HashMap的强引用
a=null; //撤销a上String的强引用,a上只有弱引用
b=null; //撤销b上String的强引用,b上有HashMap的强引用和弱引用
System.gc(); //垃圾回收
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry en = (Map.Entry)i.next();
System.out.println("map:"+en.getKey()+":"+en.getValue());//map:b:bbb
}
Iterator j = weakmap.entrySet().iterator();
while (j.hasNext()) { //a上没有强引用,只有弱引用,会自动回收
Map.Entry en = (Map.Entry)j.next();
System.out.println("weakmap:"+en.getKey()+":"+en.getValue());//weakmap:b:bbb
}
}
}
- 软引用:
SoftReference<String> softRef=new SoftReference<String>(str);
2. 软引用和弱引用的回收时机
- 对象上有强引用,不会被回收
- 如果一个对象只有软引用, 且当前虚拟机堆内存空间足够,不会回
收,反之会回收 - JVM一旦发现某块内存上只有弱引用,不管当前内存空
间是否足够,都会回收
public class ReferenceDemo {
public static void main(String[] args) {
// 强引用
String str=new String("abc");
// 软引用
SoftReference<String> softRef=new SoftReference<String>(str);
str = null; // 去掉强引用
System.gc(); // 垃圾回收器进行回收
System.out.println(softRef.get());//abc
// 强引用
String abc = new String("123");
// 弱引用
WeakReference<String> weakRef=new WeakReference<String>(abc);
abc = null; // 去掉强引用
System.gc(); // 垃圾回收器进行回收
System.out.println(weakRef.get());//null
}
}
3. 以具体案例讲述软引用的用法
- 博客管理系统里,用缓存的方式存储点击过的博文
- 定义类型为
HashMap<String, SoftReference<Content>>
的对
象类缓存博文,其中键是文章ID,值是指向Content的软引用 - 如JVM内存空间够,可以通过缓存提升性能,如果内存不够,会
释放软引用的缓存,最多影响性能,不影响功能
总结:利用软引用根据内存空间的情况来回收的特性来缓存数据。
4. 以具体案例讲述弱引用的用法
- 电商项目里,需要保存优惠券Conpon和所有用户的对应关系
- 数据结构:
WeakHashMap<Coupon, <List<WeakReference<User>>>
,键是优惠券,值是指向用户列表的弱引用
3. 假设优惠券coupon3对应100个用户,那么每个user对象上有包含
用户信息的userList上强引用和上述结构里的弱引用,不会回收(即将用户信息存放在两个列表上,一个强引用,一个弱引用)
- 当用户user1注销后, userList 里会删除该对象
- 它只有优惠券-用户关系表上的弱引用,会被自动回收
- 优惠券-用户关系会自动更新,无需干预
总结:利用弱引用会被回收和强引用不会被回收的特性来实现自动更新对象的功能。