java 中的所有软引用是否会一次性清除?

Will all the soft references in java be cleared in one single shot?

我读了这个article,现在我清楚弱引用和软引用之间的基本区别是什么。 我也明白,与弱引用不同(如果没有对该对象的强引用,它将导致对象在下一个 GC 周期中被收集),软引用将保留在内存中,直到 JVM 内存不足。

但我的问题是如果 JVM 内存不足并且垃圾收集器也开始收集软引用,它应该在逻辑上收集所有具有软引用的现有对象(我的猜测).我说得对吗?

我想到的另一件事是软引用有一个很好的用例,即内存缓存。但是如果我拥有的所有软引用都被GC一次清除,那么这可能不是我们一直想要的。

有没有办法控制将被清除的软引用的百分比?或者我们可以告诉 GC 在恢复了一定数量的内存后停止清除软引用吗?

我问这个是为了更好地掌握如何有效地使用软引用,显然没有人希望他们的缓存从内存中完全驱逐,即使你需要非常少量的记忆。

这里有更多非正式的回答:

首先,没有必要合乎逻辑立即收集所有软引用。理论上,JVM 可以(另外)跟踪上次使用情况或一些使用情况计数器。并据此做出决定(首先只清除 "older" 或 "less used" 的软引用)。或者它根据引用 "links" 到

的实际内存量对软引用进行排序

除此之外,JVM 可能会在固定的内存增量上运行。意思是:当你只有 need/want 50 MB 时,为什么要丢弃 500 MB 内存的软引用?!

换句话说:清除所有软引用是简单的"most easy to implement"策略,但不是唯一的选择。 JVM 可以自由实施各种策略。例如一个尝试删除尽可能少的软引用,以便专门支持内存缓存!

因此,除非其他一些答案可以显示 JLS 部分明确指出它们应该一次性全部清除,否则您不应根据您的 "perception" 逻辑得出结论。