JVM基础-Java中的四种引用

JVM基础-Java中的四种引用,第1张

Java中的四种引用
  • 一、强引用
  • 二、软引用
  • 三、弱引用
  • 四、虚引用
  • 五、总结
  • 六、对比

一、强引用

  • 普通变量赋值即为强引用,如A a= new A();
  • 如果一个对象具有强引用,GC绝不会回收它,当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
  • 只有通过GC Root的引用链,发现强引用不到该对象,该对象才能被回收。
二、软引用

  • SoftReference a = new SoftReference(new A());
  • 如果仅有软引用该对象时, 首次垃圾回收不会回收该对象,如果内存仍不足,再次回收时才会释放对象。即,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。
  • 注意,释放时,释放的是对象a的内存。我们可以设置软引用队列,当引用对象a被回收时,JVM会将软引用对象放入软引用队列中,软引用自身占用的内存需要配合引用队列来释放。
  • 典型例子:反射创建对象。
三、弱引用

  • WeakReference a = new WeakReference(new A());
  • 如果仅有弱引用引用该对象时,只要发生垃圾回收,就会释放该对象。
  • 注意,释放时,释放的是对象a的内存。我们可以设置弱引用队列,当引用对象a被回收时,JVM会将弱引用对象放入弱引用队列中,弱引用自身占用的内存需要配合引用队列来释放。
  • 典型例子:ThreadLocalMap中的Entry对象。
  • 弱引用与软引用的区别:只具有弱引用的对象拥有更短暂的生命周期。
四、虚引用

  • PhantomReference a = new PhantomReference(newA());
  • 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。
  • 虚引用必须配合引用队列一起使用,当垃圾回收器准备回收对象a时,如果发现对象a还有虚引用,就会在回收对象a的内存之前,把这个虚引用加入到与之关联的引用队列中。由Reference Handler线程释放其关联的外部资源(Java内存外的内存资源)。
  • 虚引用加入到引用队列中后,程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
  • 典型例子:Cleaner释放DirectByteBuffer占用的直接内存。
  • 虚引用与软引用和弱引用的区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。
五、总结
  • 虚拟机的内存不够使用,开始报警。
  • 首先,垃圾回收机制开始执行System.gc(); 回收虚引用和弱引用对象。
  • 如果弱引用对象回收完之后,内存还是报警,继续回收软引用对象。
  • 如果软引用对象回收完之后,抛出OutOfMemoryError错误,而不会被回收强引用的对象。
六、对比
引用类型被回收时间用途生存时间
强引用从来不会对象的一般状态jvm退出时终止
软引用内存不足时对象缓存内存不足时终止
弱引用垃圾回收时对象缓存gc运行之后终止
虚引用unknowunknowunknow

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/924085.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存