当前位置: 首页 > 后端技术 > Java

Java四大引用详解:强引用、软引用、弱引用、虚引用

时间:2023-04-02 00:49:26 Java

Java的四大引用详解:强引用、软引用、弱引用、幻引用本文将单独讲解@mikechenJava引用。从JDK1.2开始,对象引用分为4个层次,这样程序可以更灵活地控制对象的生命周期。这4个级别从高到低依次为:强引用、软引用、弱引用、虚引用。\Strongreferences强引用是最常见的引用。一般情况下,一个对象会被赋值给一个引用变量,而这个引用变量就是强引用。例如://对MikeChen的强引用mikechen=newMikeChen();方法内部有强引用,强引用存放在Java栈中,而真正的引用内容(MikeChen)存放在Java堆中。\\如果一个对象有强引用,垃圾收集器将不会回收该对象。当内存空间不足时,JVM宁愿抛出OutOfMemoryError异常。如果没有使用到强引用对象,需要对其进行弱化,以便GC回收,如下://帮助垃圾回收器回收这个对象mikechen=null;显式设置mikechen对象为null,或者让它超过对象的生命周期,那么GC就认为没有对该对象的引用,此时可以回收该对象。何时收集它取决于GC算法。示例:packagecom.mikechen.java.refenence;/***强引用示例**@authormikechen*/publicclassStrongRefenenceDemo{publicstaticvoidmain(String[]args){Objecto1=newObject();对象o2=o1;o1=空;系统.gc();System.out.println(o1);//nullSystem.out.println(o2);//java.lang.Object@2503dbd3}}虽然o1已经被回收了,但是o2对o1有强引用,一直存在,所以不会被GC回收。软引用软引用是弱于强引用的引用,需要用java.lang.ref.SoftReference类来实现。例如:Stringstr=newString("abc");//强引用SoftReferencesoftRef=newSoftReference(str);//软引用如果一个对象只有软引用,那么内存空间是足够的,垃圾收集器是不会回收它的。如果内存空间不足,就会回收这些对象的内存。先通过一个例子来理解软引用:/***弱引用例子**@authormikechen*/Objectobj=newObject();SoftReferencesoftRef=newSoftReference(obj);//删除强引用obj=null;//调用gc//对象仍然存在System.gc();System.out.println("gc后的值:"+softRef.get());软引用可以结合一个引用队列(ReferenceQueue),如果软引用引用的对象被垃圾回收,Java虚拟机会将软引用添加到与其关联的引用队列中。ReferenceQueuequeue=newReferenceQueue<>();Objectobj=newObject();SoftReferencesoftRef=newSoftReference(obj,queue);//删除强引用obj=null;//调用gcSystem.gc();System.out.println("gc后的值:"+softRef.get());//对象仍然存在//申请大内存,使内存空间使用达到阈值,强制gcbyte[]bytes=newbyte[100*1024*1024];//如果obj被回收,软引用会进入引用队列Referencereference=queue.remove();if(reference!=null){System.out.println("对象已被回收:"+reference.get());//Theobjectisnull}软引用通常用在对内存敏感的程序中,比如缓存。软引用在内存足够,但不够用后回收。Let'slookatthesoftreferenceusedbytheMybatiscacheclassSoftCache:publicObjectgetObject(Objectkey){Objectresult=null;SoftReferencesoftReference=(SoftReference)this.delegate.getObject(key);if(softReference!=null){????????result=softReference.get();????????if(result==null){????????????this.delegate.removeObject(key);????????}else{????????????synchronized(this.hardLinksToAvoidGarbageCollection){????????????????this.hardLinksToAvoidGarbageCollection.addFirst(result);????????????????if(this.hardLinksToAvoidGarbageCollection.size()>this.numberOfHardLinks){????????????????????this.hardLinksToAvoidGarbageCollection.removeLast();????????????????}????????????}????????}????}????returnresult;}注意:软引用对象是在jvm内存不够的时候才会被回收,我们调用System.gc()methodonlyservesasanotification.WhentheJVMscansandrecyclesobjectsisdeterminedbythestateoftheJVMitself.Evenifasoftreferenceobjectisscanned,itmaynotbereclaimed.弱引用弱引用的使用和软引用类似,只是关键字变成了WeakReference:MikeChenmikechen=newMikeChen();WeakReferencewr=newWeakReference(mikechen);弱引用的特点是无论内存是否足够,只要发生GC,就会被回收。举例说明:packagecom.mikechen.java.refenence;importjava.lang.ref.WeakReference;/***弱引用**@authormikechen*/publicclassWeakReferenceDemo{publicstaticvoidmain(String[]args){Objecto1=新对象();WeakReferencew1=newWeakReference(o1);System.out.println(o1);System.out.println(w1.get());o1=空;系统.gc();System.out.println(o1);System.out.println(w1.get());}}弱引用WeakHashMapppublicclassWeakHashMapDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{myHashMap();我的WeakHashMap();}publicstaticvoidmyHashMap(){HashMapmap=newHashMap();字符串键=新字符串("k1");字符串值="v1";map.put(键,值);System.out.println(地图);键=空;系统.gc();系统输出。打印(地图);}publicstaticvoidmyWeakHashMap()throwsInterruptedException{WeakHashMapmap=newWeakHashMap();//字符串键=“弱”;代码//想想看,如果像上面这样写会怎么样?那不是参考Stringkey=newString("weak");字符串值=“地图”;map.put(键,值);System.out.println(地图);//去除强引用key=null;系统.gc();线程.睡眠(1000);System.out.println(地图);}}当key只有弱引用时,GC发现后会自动清理key和value,作为一个简单的缓存表解决方案条目(ThreadLocal<?>k,对象v){超级(k);校准值=v;.ThreadLocalMap.Entry继承弱引用,key为当前线程实例,与WeakHashMap基本相同。幻影引用“幻影引用”,顾名思义,是没有用的。与其他类型的引用不同,幻象引用不决定对象的生命周期。如果一个对象只持有虚引用,就好像它没有引用一样,随时可能被垃圾收集器回收。幻影引用,也称为“幽灵引用”或“幻影引用”,是最弱的一类引用关系。Phantom引用需要java.lang.ref.PhantomReference来实现:Aa=newA();ReferenceQueuerq=newReferenceQueue();PhantomReferenceprA=newPhantomReference(a,rq);虚引用主要用于跟踪被垃圾收集器回收的对象的活动。幻影引用与软引用和弱引用的区别之一是幻影引用必须与引用队列(ReferenceQueue)结合使用。当垃圾回收器要回收一个对象时,如果发现它还有幻象引用,就会在回收该对象的内存之前,将这个幻象引用添加到与其关联的引用队列中。Java参考总结Java的4种参考等级从高到低分别是:强参考>软参考>弱参考>幻象参考。以上作者简介陈睿|mikechen,10年+大工厂架构经验,《BAT架构技术500期》系列文章作者,分享十余年BAT架构经验和面试心得!阅读mikechen收集的更多互联网架构Java并发|JVM|MySQL|Spring|Redis|分布式|高并发|架构师关注“mikechen的互联网架构”公众号,回复【架构】获取我的原创《300 期 + BAT 架构技术系列与 1000 + 大厂面试题答案》