「java虚引用」java弱引用软引用虚引用
今天给各位分享java虚引用的知识,其中也会对java弱引用软引用虚引用进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、java中的虚引用,有什么作用?
- 2、强引用/软引用/弱引用/虚引用解析和应用场景分析
- 3、java中虚引用是怎么回事?
- 4、java四种引用,强软弱虚 有大神在吗
- 5、Java中的强引用,软引用,弱引用,虚引用有什么用
- 6、谁能解释下JAVA中的强引用、弱引用、软引用、虚引用,尽量通俗点,谢谢!!
java中的虚引用,有什么作用?
个人理解:深入理解JAVA虚拟机一书中有这样一句描述:“为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知”。所以虚引用更多的是用于对象回收的监听,能做的功能如下:
重要对象回收监听 进行日志统计
系统gc监听 因为虚引用每次GC都会被回收,那么我们就可以通过虚引用来判断gc的频率,如果频率过大,内存使用可能存在问题,才导致了系统gc频繁调用
参考Java幽灵引用的作用
强引用/软引用/弱引用/虚引用解析和应用场景分析
我们平常普通写的 Object a=new object(); 创建对象就是一种强引用
当内存不足,JVM开始垃圾回收, 对于强引用的对象,就算是出现了OOM也不会对该对象进行回收
强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的, 即使该对象以后永远都不会被用到JVM也不会回收。 因此强引用是造成Java内存泄漏的主要原因之一。
对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,一般认为就是可以被垃圾收集的了(当然具体回收时机还是要看垃圾收集策略)。
SoftReferenceObject softReference=new SoftReference(o1);
软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集。
对于只有软引用的对象来说,
当系统内存充足时它不会被回收
当系统内存不足时它会被回收。
软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用, 内存够用的时候就保留,不够用就回收!
弱引用需要用java.lang.ref.WeakReference类来实现,它比软引用的生存期更短
对于 只有弱引用的对象 来说,只要垃圾回收机制一运行, 不管JVM的内存空间是否足够,都会回收该对象占用的内存。
软引用/弱引用应用场景
场景模拟:
假如有一个应用需要读取大量的本地图片:
如果每次读取图片都从硬盘读取则会严重影响性能,如果一次性全部加载到内存中又可能造成内存溢出。
此时使用软引用可以解决这个问题。
弱引用之WeakHashMap
它是一个特殊的HashMap,属于import java.util.WeakHashMap;与HashMap平级;
它的特殊之处在于当它的某个键值对中的键失效或者为NULL的时候.弱此时发生了GC,那么该键值对将从WeakHashMap中移除;
注意若上述的key=Integer.valueOf(5),若这里key=null,不会让map移除这个键值对,因为这里key指向的是一个值而不是一个引用,当map.put时候直接把值放进去了,所以key=null时候不会影响 WeakHashMap
下面要将虚引用,在此之前,我们需要先了解一个东西,ReferenceQueue
软引用,弱引用,虚引用在创建时候可以直接传一个对象其实他们还有另外有一个构造方法是传一个对象和一个引用队列,这样会使他们回收之前保存到Reference里.
虚引用
虚引用需要java.lang.ref.PhantomReference类来实现。顾名思义,就是 形同虚设 ,与其他几种引用都不同,虚引用并不会决定对象的生命周期。
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收 ,它不能单独使用也不能通过它访问对象, 虚引用必须和引用队列(ReferenceQueue)联合使用。
虚引用的主要作用是 跟踪对象被垃圾回收的状态 。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。 其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。
换句话说, 设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。
Java 技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
四大引用和GCroot的杂糅
java中虚引用是怎么回事?
很早Java API就添加了弱引用(WeakReference)和软引用(SoftReference),引用类在垃圾回收工作的过程中有重要作用。我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型。
这正是Java中弱引用和软引用的主要区别。如果一个对象只有弱引用指向它,垃圾回收器会立即回收该对象,这是一种急切回收方式。相对的,如果有软引用指向这些对象,则只有在JVM需要内存时才回收这些对象。弱引用和软引用的特殊行为使得它们在某些情况下非常有用。例如:软引用可以很好的用来实现缓存,当JVM需要内存时,垃圾回收器就会回收这些只有被软引用指向的对象。而弱引用非常适合存储元数据,例如:存储ClassLoader引用。
如果有类被加载,那么也没有指向ClassLoader的引用。一旦上一次的强引用被去除,只有弱引用的ClassLoader就会被回收。
Java中弱引用VS软引用
Java中有如下四种类型的引用:
强引用(Strong Reference)
弱引用(WeakReference)
软引用(SoftReference)
虚引用(PhantomReference)
强引用是我们在编程过程中使用的最简单的引用,如代码String s=”abc”中变量s就是字符串对象”abc”的一个强引用。任何被强引用指向的对象都不能被垃圾回收器回收,这些对象都是在程序中需要的。弱引用使用java.lang.ref.WeakReference class 类来表示,你可以使用如下代码创建弱引用:
代码如下:
Counter counter = new Counter(); // strong reference - line 1
WeakReferenceCounter weakCounter = new WeakReferenceCounter(counter);
//weak reference
counter = null; // now Counter object is eligible for garbage collection
现在只要你给强引用对象counter赋空值null,该对象就可以被垃圾回收器回收。因为该对象此时不再含有其他强引用,即使指向该对象的弱引用weakCounter也无法阻止垃圾回收器对该对象的回收。相反的,如果该对象含有软引用,Counter对象不会立即被回收,除非JVM需要内存。Java中的软引用使用java.lang.ref.SoftReference类来表示,你可以使用如下代码创建软引用:
代码如下:
Counter prime = new Counter(); // prime holds a strong reference _ line 2
SoftReference soft = new SoftReference(prime) ; //soft reference variable has
SoftReference to Counter Object created at line 2
prime = null; // now Counter object is eligible for garbage collection but only be
collected when JVM absolutely needs memory
强引用置空之后,代码的第二行为对象Counter创建了一个软引用,该引用同样不能阻止垃圾回收器回收对象,但是可以延迟回收,与弱引用中急切回收对象不同。鉴于软引用和弱引用的这一区别,软引用更适用于缓存机制,而弱引用更适用于存贮元数据。另一个使用弱引用的例子是WeakHashMap,它是除HashMap和TreeMap之外,Map接口的另一种实现。
WeakHashMap有一个特点:map中的键值(keys)都被封装成弱引用,也就是说一旦强引用被删除,WeakHashMap内部的弱引用就无法阻止该对象被垃圾回收器回收。
虚引用是java.lang.ref package包中第三种可用的引用,使java.lang.ref.PhantomReference类来表示。拥有虚引用的对象可以在任何时候被垃圾回收器回收。和弱引用和软引用相似,你可以通过如下代码创建虚引用:
代码如下:
DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong
reference _ line 3
PhantomReference phantom = new PhantomReference(digit); // phantom reference to object created at line 3
digit = null;
一旦移除强引用,第三行的DigitalCounter对象可以在任何时候被垃圾回收器回收。因为只有一个虚引用指向该对象,而虚引用无法阻止垃圾回收器回收对象。
除了了解弱引用、软引用、虚引用和WeakHashMap,还需要了解ReferenceQueue。在创建任何弱引用、软引用和虚引用的过程中你可以通过如下代码提供引用队列ReferenceQueue:
代码如下:
ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
DigitalCounter digit = new DigitalCounter();
PhantomReferenceDigitalCounter phantom = new
PhantomReferenceDigitalCounter(digit, refQueue);
引用实例被添加在引用队列中,你可以再任何时候通过查询引用队列回收对象。一个对象的生命周期可以通过下图进行描述:
在新窗口打开图片
这就是Java中弱引用和软引用的区别。我们还学到了一些基本的引用类:弱引用、软引用、虚引用以及WeakHashMap和WeakHashMap。总之,合理的使用引用可以帮助垃圾回收器更好的管理Java内存。
java四种引用,强软弱虚 有大神在吗
Java中四种引用的特点:
强引用(StrongReference)
当我们使用 new 这个关键字创建对象时创建出来的对象就是强引用(new出来对象为强引用) 如Object obj = new Object() 这个obj就是一个强引用了,如果一个对象具有强引用。垃圾回收器就不会回收有强引用的对象。如当jvm内存不足时,具备强引用的对象,虚拟机宁可会抛出OutOfMemoryError(内存空间不足),使程序终止,也不会靠垃圾回收器去回收该对象来解决内存。
2.软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。
软引用的作用:软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3.弱引用(WeakReference)
如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4.虚引用(PhantomReference)
“虚引用”顾名思义,就是形同虚设,和其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有 虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
ReferenceQueue queue = new ReferenceQueue ();
//虚引用对象
PhantomReference pr = new PhantomReference (object, queue);
程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
如果你还想深入了解的话给你推荐一个博文地址:
网页链接
Java中的强引用,软引用,弱引用,虚引用有什么用
这两天在看 Reference 相关的东西,虽然接触到的场景不多,但感觉还是比较有用的。
在非常关心内存的情况下,有可能能派上用场。
在涉及到某一个对象被 GC,需要得到通知,然后再做某些相关处理的时候,有可能派得上用场。
对于第一点,目前接触到的就是 WeakHahsMap。像我们平常写缓存的时候,最简单的就是在一个类中
public static MapString,String user_map = new HashMapString, String();
然后再在全局使用它。这里就可以参考下 Tomcat 实现的这个 LRU 缓存:tomcat/ConcurrentCache.java at trunk · apache/tomcat · GitHub,它就用到了 WeakHashMap,WeakHashMap也用到了 WeakReference,可以参考下。
WeakHahsMap 的实现原理简单来说就是里面的 Entry 使用继承了 WeakReference,那么当 Entry 的 key 不再被使用的时候,也就是被 GC 的时候,那么该 Entry 就会进入到 ReferenceQueue 中, WeakHashMap 在你调用相关方法的时候,那么就会把这个 Entry 从 ReferenceQueue 中删除,并且做相关处理(也就是把这个 key 删除)。这时候你就会发现,你的一个键值对没有了。
对于第二点,目前接触到的就是一个 FileCleaningTracker,它的作用是,把一个文件和一个对象关联起来,当这个对象被 GC 的时候,文件也帮我们删除掉。
FileCleaningTracker 的实现简单来说就是用了一个虚引用。它里面有一个 Tracker 的内部类,他继承自 PhantomReference,你可以理解成 WeakHashMap中的 Entry(其实也很像了)。这个 Tracker 就和我们的关联对象 marker 关联起来(你可以理解成 WeakHashMap 中的 Entry 的 key),那么当 marker 被回收的时候,Tracker 就会被GC 弄到 ReferenceQueue 中,那么 FileCleaningTracker 就会把 Tracker 从 ReferenceQueue 移除出来,并且执行相关操作(delete file)。
最后:
自己理解的引用(强,软,弱虚)是和 GC 比较相关的,能够在一个 对象被 GC 的时候,应用程序得到通知,然后执行相关操作。像 WeakHashMap 就是这样,底层发现 key 没了,上层就把 entry 删了。
ps:
第6条:消除过期对象的引用(WeakHashMap的缓存应用):愿无岁月可回首
第6条:WeakHashMap扩展知识1(原理与Reference相关):愿无岁月可回首
第6条:Reference应用-FileCleaningTracker:愿无岁月可回首
最后的最后补充。。。
突然想起,之前自己在工作中涉及到这样一种情况,我需要对用户投资的钱进行一个每日的加息,有一天客户忘了把加息的数据给我,然后给了我一份 csv 文件,让我加上。我当时的做法是,让运维把文件放在固定的地方,程序读取,执行逻辑,然后运维再手动删除。 这个时候,其实也可以通过这种 FileCleaningTracker,当读取完之后,自动的删除这个文件,就不用运维来做了。(这可能是一种应用场景)
谁能解释下JAVA中的强引用、弱引用、软引用、虚引用,尽量通俗点,谢谢!!
1.强引用
本章前文介绍的引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
2.软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3.弱引用(WeakReference)
如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4.虚引用(PhantomReference)
"虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃 圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解
被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
java虚引用的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java弱引用软引用虚引用、java虚引用的信息别忘了在本站进行查找喔。
发布于:2022-12-25,除非注明,否则均为
原创文章,转载请注明出处。