猿问

弱引用可维护性

我正在阅读 java 中的弱引用,听起来很简单,如果一个对象只有弱引用,那么它可以被垃圾收集器收集。除了如果您的引用在使用该值之前失效会发生什么?

例子:

假设我有一个键为 {1,2,3,4,5} 的弱哈希映射,所有值都为 1。现在假设您有一个用于 [1:10] 中数字的随机数生成器。现在每次得到这个数字时,它都会检查它是否是映射中的一个键,然后给出一个对该键的临时强引用。因此,通过此设置,您将拥有一些具有强引用的键,因此会留在内存中,但您也有可能在选择之前某些键已失效。

如果我对弱哈希映射的直觉是正确的,那是否意味着映射将在某个时候从其原始状态改变?


不负相思意
浏览 146回答 3
3回答

慕神8447489

尝试使用Integer对象作为 a 的键WeakHashMap可能会导致一些奇怪的行为。首先,javadoc forWeakHashMap有以下注释:此类主要用于其等于方法使用 == 运算符测试对象身份的关键对象。一旦这样的键被丢弃,它就永远不会被重新创建,所以以后不可能在 WeakHashMap 中查找该键,并且会惊讶于它的条目已被删除。此类将与关键对象完美配合,这些对象的 equals 方法不基于对象标识,例如 String 实例。然而,对于这种可重新创建的键对象,自动删除键已被丢弃的 WeakHashMap 条目可能会令人困惑。考虑以下代码:&nbsp; &nbsp;WeakHashMap<Integer, String> map = new WeakHashMap<>();&nbsp; &nbsp; Integer k = Integer.valueOf(9001);&nbsp; &nbsp; map.put(k, "OVER 9000!?");&nbsp; &nbsp; while (true)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(map.get(k));&nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; k = Integer.valueOf(9001);&nbsp; &nbsp; &nbsp; &nbsp; System.gc();&nbsp; &nbsp; }循环将从打印“OVER 9000!?”开始,但在第一个循环之后,原始键已被丢弃(即使现在有一个equals对它的键的引用)。结果,如果该键对象被垃圾收集,则条目将从地图中删除,并且循环将开始打印“null”。由于我们System.gc();在丢弃密钥后调用,因此这很可能发生在单个循环之后。但这并不是Integer作为WeakHashMap密钥使用的问题的结束。如果将上面的值 9001 更改为 1,您会发现行为发生了变化!(可能?这可能取决于实现。)现在,条目永远不会从地图中删除。这是因为整数缓存——Integer.valueOf(1)总是返回相同的Integer实例,但每次都会Integer.valueOf(9001)创建一个新Integer实例。第二个问题特定于Integer,但第一个问题实际上适用于您尝试在equals不基于 的情况下使用密钥的任何方案==。如果equals 是基于==,那么你的问题并没有真正适用-如果你没有很强的参考钥匙了,也不要紧,是否值被从地图上删除,因为你不再有办法得到它——你不能重新创建一个使用基于身份的平等的密钥。
随时随地看视频慕课网APP

相关分类

Java
我要回答