【Java】通过软引用和弱引用提高JVM内存性能

引用:

  1. 强引用:指在程序代码中普遍存在的,类似Object obj = new Object(),只要强引用在,GC不会回收掉被引用的对象。
  2. 软引用:有用但并非必须的对象。在系统要发生内存溢出异常之前,先把这些对象二次回收,如果还没有足够内存,则抛  出内存溢出异常。
  3. 弱引用:比软引用更弱的非必需对象,此类对象只能生存道下一次GC之前,GC时无论内存是否够用,都会回收此类对象。
  4. 虚引用:最弱,为一个对象设置虚引用唯一目的时能在这个对象被GC时收到一个系统通知。

 

对比软引用和弱引用:

        通过以下代码,都先创建一个强引用,第一个str赋给弱引用,第二个test赋给弱引用,在之后都分将强引用置为null,启动垃圾回收,可见软引用由于当前内存 空间足够,不进行GC,而弱引用无论如何都会被GC,所以输出为null。

import java.lang.ref.SoftReference;//import 软引用
import java.lang.ref.WeakReference;//import 弱引用

/**
 * 比较软引用和弱引用
 * @author 袁盛桐
 */
public class SoftandWeakReference {
	public static void main(String[] args) {
		//创建强引用
		String str = new String("soft");
		//软引用 
		SoftReference<String> softRef = new SoftReference<String>(str);
		//去掉强引用
		str = null;
		//启动垃圾回收
		System.gc();
		System.out.println(softRef.get());
		
		System.out.println("############");
		
		//创建强引用
	    String test = new String("weak");
	    //弱引用
	    WeakReference<String> weakRef = new WeakReference<String>(test);
		//去掉强引用
		test = null;
		//启动垃圾回收
		System.gc();
		System.out.println(weakRef.get());
	}
}

运行结果:

使用软引用来提升性能

         例如一个访问量很高的博客系统,我们可以通过把最常访问的文章放进内存中,因为这样不用访问数据库可以提高访问及处理速度,如果都是使用强引用的话会降低性能,造成内存溢出异常。

          如果使用软引用,假设定义一个类content,其中包含文章作者,内容等,再建立一个HashMap<String, SoftReference<Content>>,键为string类型,表示文章id,SoftReference表示指向content的软引用。用户访问后,如果没有的话从数据库查询出来,为强引用,在访问结束后,设置为软引用,这样在大规模文章存在内存后导致空间不够时,启动垃圾回收,可以释放内存,避免异常。

 

使用弱引用WeakHashMap

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
class WeakHashMapDemo{
    public static void main(String[] args) throws Exception{
        String a = new String("a");//分配一块空间假设首地址1000,创建强引用
        String b = new String("b");//分配一块空间假设首地址2000,创建强引用
        Map weakmap = new WeakHashMap();
        Map map = new HashMap();
        //在两个HashMap中插入两个键值对
        map.put(a,"aaa");//1000上有两个强引用
        map.put(b,"bbb");//2000上有两个强引用
        weakmap.put(a,"aaa");//分别加一个弱引用
        weakmap.put(b,"bbb");
        map.remove(a);//1000去掉一个强引用,只剩一个强和一个弱
        a = null;//只剩一个弱
        b = null;//剩一个强一个弱
        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());
        }
        Iterator j = weakmap.entrySet().iterator();
        while(j.hasNext()){
            Map.Entry en = (Map.Entry)j.next();
            System.out.println("weakmap:"+en.getKey()+":"+en.getValue());
        }
    }
}

 

当一个对象只用弱引用时,这个对象会在下次GC时被回收

例如,在电商项目中,可以使用一个coupan类来存储优惠券信息,包含打折程度有效日期和商品范围之类的,从数据库中取得所有优惠卷之后,用list<coupan>类型的coupanlist来储存优惠卷。

用WeakHashMap<coupan,List<WeakReference<User>>>来储存优惠卷和他所关联的用户,键值时coupan类型,值指向list<user>用户列表的弱引用。

如果有1000张优惠卷,他们会储存在coupanlist中,同时WeakHashMap<coupan,List<WeakReference<User>>>会以键值的形式储存1000张优惠卷。同时,假设有10万用户,例如coupan1会储存对应的其中500用户,其中weakuserlist以弱引用方式保存coupan1对应的500用户。

当优惠卷和用户发生变更时,他们对应的关系就能自动进行更新

  1. 假如当coupan5这个券失效时,从coupanlist中去掉这个对象,这样weakcoupanhashmap中之后其弱引用,下次GC时候就会自动回收。
  2. 假如coupan9对应的100用户中,用户user56注销了账号,他会被从userlist中移除,而List<WeakReference<User>>中只有其弱引用,下次GC时会被自动回收。

由此可以看出,这种弱引用的使用可以带来“自动更新”的效果,同时在用户量和优惠券量极大时,通过GC垃圾回收可以有效的释放空间,带来便利,提高系统性能。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值