java的4大引用你了解了嘛

文章很长文末有福利

1. 强引用(StrongReference)

我们平常使用new操作符来创建的对象就是强引用对象,只要有一个引用存在,垃圾回收器永远不可能回收具有强引用的对象。

Object obj=new Object();

注意:

强引用的对象并不是永远不会被回收,需要把obj值为null,或者超出对象的生命周期之后,GC就有机会去回收它,具体什么时候回收要看GC。还有,这里的StrongReference只是一个对强引用的称呼,在java中并没有对应的实体类。

2. 软引用(SoftReference)

软引用是用来描述一些还有用但并非必须的对象。当内存充足时,垃圾回收器不会清理具有软引用的对象,只有当内存不足时垃圾回收器才会去清理这些对象,如果清理完软引用的对象后内存还是不足才会抛出异常。软引用在java中也是一个对象,对应的实体类是SoftReference案例:

这个案例我们事先把最大堆内存改为了24M

-Xmx24M

/**  * 软引用demo  * SoftReference  * 1.当内存不足的时,JVM就会把软引用对象进行回收  * 2.如果回收后还是没有足够的内存,才会抛出内存溢出异常  */publicstaticvoidmain(String[]args)throwsInterruptedException{SoftReference<byte[]>s=newSoftReference<>(newbyte[1024*1024*10]);//10mSystem.out.println(s.get());System.gc();//启动GCThread.sleep(500);System.out.println(s.get());//再创建一个数组,堆中存不下的时候,垃圾回收器工作//先回收一次,如果第一次回收后内存还是不够//则再清理第二次,这一次会把软引用对象清除byte[]b=newbyte[1024*1024*15];//15mSystem.out.println(s.get());//null}

控制台打印结果

[B@2a139a55

[B@2a139a55

null

此外,还可以通过以下JVM参数来打印GC日志

-XX:+PrintGC//打印简单的GC日志-XX:+PrintGCDetails//打印详细的GC日志

通过控制台的打印结果我们得出结论:内存充足的情况下,具有软引用的对象不会被垃圾回收器回收,当再次创建了新的对象,结果导致堆内存不足时就会启动第一次GC,这一次不会回收软引用关联的对象,但是当第一次清理之后发现内存还是不够,则会再启动第二次GC,这一次GC才会清理掉软引用关联的对象。

由于,在JAVA中软引用也是一个类,我们需要软引用需要创建软引用类实例,我们在上面案例中,变量s的引用指向的是new SoftReference()这个实例对象,属于强引用关系,而在这个实例对象的里面又去引用了我们new出来的byte数组实例,这个引用是软引用关系。

SoftReference<byte[]>s=newSoftReference<>(newbyte[1024*1024*10]);

关系图如下:

软引用非常适合用在缓存中,假如用户访问的系统中需要加载很多图片,内存够用的时候可以缓存很多图片,假如内存不够用了,再把图片先回收掉也无妨,下次需要的时候再加载一次即可。

3. 弱引用(WeakReference)

无论内存够不够,只要垃圾回收器启动,弱引用关联的对象肯定被回收。

弱引用对象的实体类是WeakReference。

案例:

/**  * 弱引用demo  * WeakReference  * 不管内存够不够,都会进行回收  */publicstaticvoidmain(String[]args){WeakReference<Object>w=newWeakReference<Object>(newObject());System.out.println(w.get());System.gc();System.out.println(w.get());}

控制台打印结果

java.lang.Object@2a139a55

null

可以看出,弱引用关联的对象只能存活到下一次启动GC之前。

弱引用可以用来解决内存泄露的问题,比如:ThreadLocal中的key就使用到了弱引用来防止内存泄露,ThreadLocal的相关文章在末尾。

关系图如下:

4. 虚引用(PhantomReference)

虚引用,又称作幻象引用,如果一个对象具有虚引用,那么它和没有任何引用一样,被虚引用关联的对象引用通过get方法获取到的永远为null,也就是说这种对象在任何时候都有可能被垃圾回收器回收,通过这种方式关联的对象也无法调用对象中的方法。虚引用主要是用来管理堆外内存的,通过ReferenceQueue这个类实现,当一个对象被回收的时候,会向这个引用队列里面添加相关数据,给一个通知。

案例一:

Objectobj=newObject();PhantomReference<Object>objRef=newPhantomReference<Object>(obj,null);System.out.println("获取虚引用所指向的对象"+objRef.get());System.out.println(objRef.get().equals(obj));//尝试调用对象中的方法

控制台打印结果

虚引用配合ReferenceQueue类,可以用来管理堆外内存,如果虚引用对象被回收后,会向引用队列里面发送一个通知,可以参考以下demo便于理解。

案例二:

/** * 虚引用 *  管理堆外内存 */publicclassTest_PhantomReference{//引用队列privatestaticfinalReferenceQueue<Object>QUEUE=newReferenceQueue<>();publicstaticvoidmain(String[]args){//当虚引用对象被回收时,会把一个信息填入到引用队列中PhantomReference<Object>p=newPhantomReference<Object>(newObject(),QUEUE);System.out.println("第一次获取虚引用指示的对象"+p.get());//nullSystem.out.println("第一次获取虚引用的地址值"+p);List<byte[]>list=newArrayList<>();newThread(()->{booleanflag=true;try{while(flag){//不断去new新的对象,内存不足时GC就会启动list.add(newbyte[1024*1024]);}}catch(Exceptione){e.printStackTrace();}finally{flag=false;System.out.println("第二次获取虚引用指示的对象"+p.get());}}).start();/* 再开启一个线程,做一个监控  * 当虚引用被回收时,会发送一个通知  * 如果引用队列QUEUE中不再是null  * 证明虚引用已经被回收  */newThread(()->{booleanflag=true;while(flag){Reference<?extendsObject>poll=QUEUE.poll();if(poll!=null){flag=false;System.out.println("虚引用对象"+poll+"被回收了");}}}).start();}}

虚引用可以用来管理堆外内存,以上案例中我们结合了一个Queue来进行测试,开启一个线程来进行监控,假如虚引用对象被回收那么通过poll方法就可以得知。

《 Java学习、面试;文档、视频资源免费获取》

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