Java为什么需要人为设置弱引用

弱引用,是为了告诉gc,如果内存不足的话,可以释放这个变量。

但是,就我的了解,变量就算不标记为弱引用,gc一样可以识别出某个变量已经没用,可以释放。

那干嘛还要人为去设置为弱引用呢?而且被设置为弱引用,还有可能变量突然被gc丢的情况,影响代码的逻辑咯?

阅读 3.2k
4 个回答

内存不够的时候

GC 直接回收弱引用,释放内存

没有弱引用,只有强引用的时候,就 OutOfMemoryException 了

java的引用分那么几类:
强引用: 一般new出的对象, 内存不足时, 如果还被引用, 也不会GC掉;
软引用: GC时如果内存不够, 就会GC掉;
弱引用: GC就干掉, 管他有内存够不够用;
虚引用: 甚至感觉不到他的存在;

看这个分类, 猜测为什么要设置引用分类, 可能就是为了在jvm不同状况下对内存管理的动态性和灵活性吧;

场景:设计一个单例类,利用一个类变量存储多个线程的参数

设计一:

public class InstanceA {
   private static Map<Thread, Object> map = new HashMap<>();
}
  • 缺陷一:线程不安全

设计二:

public class InstanceA {
   private static Map<Thread, Object> map = new ConcurrentHashMap<>();
}
  • 缺陷一:线程退出,无法自动清除参数,久而久之造成内存泄漏并溢出
  • 缺陷三:悲观锁,性能损耗

设计三:

public class InstanceA {
   private static Map<<WeakReference<Thread>>, Object> map = new ConcurrentHashMap<>();
}
  • 缺陷一:悲观锁,性能损耗
  • 优化项一:需要手动定期清理Mapkeynullvalue
  • 优化项二:不能存储多个参数

设计四:

public class InstanceA {
   private static ThreadLocal<Object> map = new ThreadLocal<>();
}
  • 优点一:无锁
  • 优点二:可以储存多个参数
  • 优点三:在每次get/set时,自动清理(底层依赖WeakReference
弱引用,是为了告诉gc,这个变量没用了,下次可以释放。

并不是“因为要回收”所以才设置弱引用
弱引用的意思是:别人还在用我就留着,别人都不用了我就扔了。强引用和软引用都做不到这个效果

参考https://www.baeldung.com/java-weak-reference

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题