白话java软引用、弱引用

引言:

java中、软引用和弱引用的概念以及作用非常晦涩难懂。因为不经常使用,就算是经验丰富的程序员也搞不清楚这两个概念。本文将用一个场景通过白话方式阐述这两个概念的含义以及作用。

正文:

以前有个村子,村子里面有个地主,地主和他老婆经常会雇佣短工给自己打工。刚好村子外面有座山,山上住着一些淳朴的山民。地主就经常去山上找一些山民给自己做短工。这些被雇佣的山民就住在地主家干活。农忙的时候,地主就多雇了几个,可过了农忙季节,也不需要这么多短工了,地主他老婆就时不时把这些多余的短工赶回山上去,只留一部分干活的。等过段时间,再去山上叫人。这些山民也老实,地主每次来叫都会跟着地主来打会工,地主老婆说让他们回去,他们也老老实实回去。就这样,虽然来来回回有些麻烦,大家都觉得还挺好。
后来有个算命先生来了,见了此番场景,盘了盘手里的核桃,对地主说:“你每次去山里叫这些人下山给你打工,路上可要不少盘缠,一路跟着你回家也要花不少时间。要是这些人没活干,你叫你老婆别急着赶他们走,在村口搭个棚子,稍微给他们些吃穿用度,让他们先在村口候着。要是突然来事情了,你直接在外面叫他们来干活。这不就省下了去山上叫他们的来回盘缠和时间了吗?”。算命先生看见地主听得出神,微微一笑,得意地45°角看天空,小毡帽掉下来,露出来秃顶的脑袋。
地主回了神,眼里冒着精光,赶紧捡起地上的小毡帽给算命先生递过去。
“先生妙计,这个法可真绝!可...”。
“可什么?”。
“搭个棚子是没什么难的,可天天供着他们,这也是不小的开销。”。
“那还不简单,不需要天天养着,你要是农忙活多,让你老婆先别急着赶人,叫他们多住几日。就这几天的吃食,可比来回上山的开销省多了。再者,你让你老婆赶人的时候,看着点,要是哪些老弱病残在大棚住着,就尽快赶他们走,要是些精壮的汉子,经常用到他们,那就再缓缓。”
最后地主就采取了算命先生的方法,发现真的又省时间又省事。农忙的时候部分短工会闲下来住到村口大棚,又有活干了,就又叫回去。遇到地主家也没什么余粮的时候,再把大棚里的人统统赶走。

故事说完了,其实地主就是jvm,地主老婆就是gc线程,短工就是对象实例,去山上叫人就是jvm创建对象。至于大棚区的住户,就是被软引用(精壮男人)和弱引用(老弱病残)的工人。
若对象(短工)没有软引用和弱引用,就直接就被gc了(没资格住大棚区),若是弱引用(老弱病残),其实也会马上被gc的,优势就是在被gc前,可以重新回地主家打工成为强引用。若是软引用(精壮男人),不太会被gc掉(会比较长的待在大棚区),除非jvm内存gc多次发现内存还是不够用,那么也是会释放软引用的对象的(地主家实在也没余粮了)。

实际代码

自己写了两个内部类,重写toString,用来输出;对象简单点直接用字符串对象。
这里引入一个类:ReferenceQueue,它是会在对象被gc时,把对象的弱引用、软引用添加到这个队列中,就好像从大棚离开的工人排队迈上了返乡之路,。

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

class Scratch {
    public static void main(String[] args) {
//        soft();
        weak();
    }

    /**
     * “精壮”软引用
     */
    public static void soft(){
        ReferenceQueue queue = new ReferenceQueue();//“返乡队列”,被gc的对象会在这个队列中插入对象的软引用"SoftReference"
        String work = new String("worker");//强引用:work
        MySoftReference softReference = new MySoftReference(work,queue);
        System.out.println(softReference.get());//根据软引用找到对象
        work = null;//工人离开地主家工位,到地主家附近休息,即对象失去强引用,由于指定了软引用,因此会去大棚休息
        System.out.println(softReference.get());//根据软引用找到对象,可在此处赋值给变量转化为强引用
        System.gc();// 地主老婆来赶人,因为是“精壮的”软引用,【所以不会被gc,继续留在大棚区,这里和弱引用不同】
        System.out.println(queue.poll());//对象【未】被gc,则poll结果为null
        System.out.println(softReference.get());//由于是精壮的软引用,所以一次gc是不会被gc掉的,只有gc成功才会进返乡队列,所以这里poll得到的结果为null,若多次gc后,jvm认定当前空间紧缺,把软引用也gc了,此时poll会得到该对象的软引用
    }

    /**
     * “老弱病残”弱引用
     */
    public static void weak(){
        ReferenceQueue queue = new ReferenceQueue();//“返乡队列”,被gc的对象会在这个队列中插入对象的弱引用"WeakReference"
        String work = new String("worker");//强引用:work
        MyWeakReference weakReference = new MyWeakReference(work,queue);
        System.out.println(weakReference.get());//根据弱引用找到对象
        work = null;//工人离开地主家工位,到地主家附近休息,即对象失去强引用,由于指定了弱引用,因此会去大棚休息
        System.out.println(weakReference.get());//根据弱引用找到对象,可在此处赋值给变量转化为强引用
        System.gc();// 地主老婆来赶人,因为是老弱病残的弱引用,【直接赶人】
        System.out.println(queue.poll());//对象被gc,会往queue中放引用对象,则poll结果为引用对象
        System.out.println(weakReference.get());//再根据弱引用去大棚找人肯定找不到了
    }

    public static class MyWeakReference extends WeakReference{

        public MyWeakReference(Object referent) {
            super(referent);
        }

        public MyWeakReference(Object referent, ReferenceQueue q) {
            super(referent, q);
        }

        @Override
        public String toString() {
            return "MyWeakReference{}";
        }
    }
    public static class MySoftReference extends SoftReference {

        public MySoftReference(Object referent) {
            super(referent);
        }

        public MySoftReference(Object referent, ReferenceQueue q) {
            super(referent, q);
        }

        @Override
        public String toString() {
            return "MySoftReference{}";
        }
    }
}

可以用软引用和弱引用的特性做缓存,使用弱引用、软引用做缓存可重新利用即将被gc的对象,省去了创建对象的开销。软引用相比弱引用留存的时间更长。

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

推荐阅读更多精彩内容