你会使用软引用和弱引用吗?

这篇文章我们来聊聊软引用和弱引用对内存性能的帮助,大家在平时的开发过程中,对于内存性能做过哪些调优工作,其中的一个方法就是我们可以使用软引用和弱引用。

软引用和弱引用的定义

  • 软引用(SoftReference):

如果一个对象只具有软引用,而当前虚拟机堆内存空间足够时,那么垃圾回收器就不会回收它,反之就会回收当前软引用指向的对象。

  • 弱引用(WeakReference):

垃圾回收器发现一个对象上只有弱引用,此时不管内存够不够,这个对象都会被回收。

下面通过一段简单的代码来看一下软引用和弱引用的具体用法;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class ReferenceDemo {
    public static void main(String[] args) {
        //强引用
        String str = new String("abc");
        //弱引用
        SoftReference<String> softRef = new SoftReference<>(str);
        str = null; //去掉强引用
        System.gc();    //垃圾回收器进行回收
        System.out.println(softRef.get());

        //强引用
        String abc = new String("123");
        //弱引用
        WeakReference<String> weakRef = new WeakReference<>(abc);
        abc = null; //去掉强引用
        System.gc();    //垃圾回收器进行垃圾回收
        System.out.println(weakRef.get());
    }
}

通过上面这个例子,我们来分析一下软引用和弱引用的差别,首先看弱引用的例子,我们先定义了一个强引用对象,然后我们给这个强引用对象加了一个软引用,这里要注意软引用的写法是SoftReference,然后我们通过str = null来去掉str对象的强引用,此时str这个对象只有一个软引用,通过System.gc();我们进行了一次垃圾回收,因为str这个对象只有一个弱引用,没有强引用,而这是内存足够,所以说这个对象是不会被垃圾回收器回收的,它的输出是abc。

然后我们看第二个例子,首先定义了一个强引用对象,然后给这个对象加了一个弱引用,这里给对象加弱引用的方法是WeakReference,我们再通过abc = null,去掉这个对象的强引用,此时abc这个对象就只有一个弱引用,通过System.gc()进行了一次垃圾回收,这个适合abc这个对象没有强引用,只有一个弱引用,根据弱引用的定义,在垃圾回收之后,这个对象会被回收的,所以说弱引用的输出结果是null。

那么最终的结果是不少我们分析的这样,我们run一下看看,如下图所示,只有弱引用的对象在内存空间足够的时候没有被回收,对象在只有弱引用的时候被垃圾回收器回收。

软引用的使用场景:

比如说在一个博客管理系统里,为了提升访问性能,用户在点击博文时,如果这篇博文有缓存,这样其他用户在点击这篇博文时,就直接从内存中加载,而不走数据库,而这样可以降低响应时间,首先,我们定义一个Content类,来封装博文的内容,

然后我们定义一个类型为HashMap<String,SoftReerence<Content>>对象来保存缓存内容,其中键是String类型表示文章id,值是一个指向Content的软连接,随后当用户点击某个id时,用id去HashMap中找,如果找到,并且Content的内容不为空,那么从中拿数据并直接做展示动作,这样的话,不要查询数据库,可以提高性能。在其中用id找不到,或者虽然找到,但是其中内容为空,那么我们就从数据库里面去找,找到文章后同时把它插入到HashMap这个缓存中,这个地方要注意,插入缓存后要删除Content上的强引用,从而保证只有一个软引用。

这样用软引用的好处,假设我们用1GB的内存,缓存了10000篇博文,那么这10000篇博文,在内存空间上只有软引用,没有强引用,如果内存空间足够时,那么我们可以通过缓存来提升性能,但是万一内存不够,我们可以依次释放这10000篇博文占用的内存,而释放时不会影响业务流程,最多就是稍微影响性能。

对比一下,如果这里我们用强引用来做缓存,会有什么后果,由于我们不知道什么时候该撤销在Content上的强引用,所以说找不到一个合适的机会来释放缓存。如果我们再引入一套缓存机制,这就属于额外工作了,就没有像软引用这样直接了。

弱引用的使用场景:

在某个电商网站中,我们会用Coupon类来保存优惠券信息,比如我们其中可以定义优惠券打折程度,有效期和作用范围等等,当我们从数据库中,得到所有的优惠券信息之后,会用一个List<Coupon>类型来保存优惠券,这个时候,如果我们想保存优惠券和它关联的用户时,我们可以用WeakHashMap<Coupon,List<WeakReference<USer>>>这样类型的weakCouponHM对象,这样的对象,它主体是WeakHashMap,也就是基于弱引用的HashMap,其中键是Coupon类型,值是指向List<WeakReference<User>>的弱引用,想象一下,如果有一百个优惠券,那么它会存储在List<Coupon>类型中的couponList中,同时在WeakHashMap这个类型对象里,也会用键的形式存储这100个优惠券。加入有10000个用户,我们可以用List<User>类型的userList对象来保存它们。

我们假设coupon1这个优惠券对应100个用户,那么我们可以通过weakCouponHM.put()方法来添加它们的对于关系,其中是以弱引用的方法, 保存了coupon1所对应的100个用户,同理,当假设某个优惠券3,用弱引用的方式指向这100个用户,当某个用户注销账户时,它会从List<User>这个对象中删除,换句话说,这个对象就只有在weakCouponHM里面的值,也就是只有一个弱引用,在下次垃圾回收的时候回被清除,这样coupon3上关联的用户它会被自动更新成99个。

相比之下,我们不用弱引用而选择用强引用,那么我们就在用户被删除之后,需要手动删除用户和优惠券之间的对应关系,如果忘了删除就会出现代码问题,相比之下,当我们引用弱引用时,就会给我们带来“自动更新”这样的好处。

更多Java相关文章、资料,可以关注公众号故里学Java,回复资源包获取

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271