ToB企服应用市场:ToB评测及商务社交产业平台

标题: 强引用、软引用、弱引用、虚引用有什么区别? [打印本页]

作者: 三尺非寒    时间: 2022-8-31 18:49
标题: 强引用、软引用、弱引用、虚引用有什么区别?
强引用、软引用、弱引用、虚引用 · 语雀 (yuque.com)
自 JDK1.2 开始,Java 提供了 4 种引用关系,以表示引用和实例对象的关系。
强引用“一直存活着”

强引用,就是我们最常见的普通对象引用。
只要强引用还存在,垃圾收集器永远不会回收掉被引用的实例对象。
  1. Object o = new Object();
复制代码
软引用“有 n 次活的机会”

在系统将要发生内存溢出异常之前,垃圾收集器会把只被软引用关联着的实例对象进行回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常(OutOfMemoryError)。
软引用通常用来实现内存敏感的缓存:
这样就保证了使用缓存的同时,不会耗尽内存。
  1. SoftReference<Object> softO = new SoftReference<>(new Object());
复制代码
弱引用“回收就会死亡”

被弱引用关联着的实例对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的实例对象。
弱引用可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。弱引用同样是很多缓存实现的选择。
  1. WeakReference<Object> weakO = new WeakReference(new Object());
复制代码
虚引用“随时可能被回收”

虚引用也称为“幽灵引用”或者“幻影引用”,虚引用是最弱的一种引用关系。
无法通过虚引用来获取一个实例对象。
虚引用主要用来跟踪对象被垃圾回收的活动,回收对象关联的资源。
在Java 8以及之前的版本中,当垃圾收集器准备回收一个实例对象时,如果发现它还有虚引用,就会在回收实例对象之前,把这个虚引用加入到与之关联的引用队列中。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动,然后断开虚引用对象的引用,虚引用被回收或者不可达,虚引用指向的对象才会回收。
  1. Object counter = new Object();
  2. ReferenceQueue refQueue = new ReferenceQueue<>();
  3. PhantomReference<Object> p = new PhantomReference<>(counter, refQueue);
  4. counter = null;
  5. System.gc();
  6. try {
  7.     // Remove 是一个阻塞方法,可以指定 timeout,或者选择一直阻塞
  8.     Reference<Object> ref = refQueue.remove(1000L);
  9.     if (ref != null) {
  10.         // do something
  11.         
  12.         ref = null;
  13.     }
  14. } catch (InterruptedException e) {
  15.     // Handle it
  16. }
复制代码
参考资料

第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?

ThreadLocal 原理分析及内存泄漏演示

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4