Java 中的字符串池是否表现得像 LRU 缓存?

Does String Pool in Java behaves like LRU cache?

字符串是不可变的,在字符串池中进行管理。我想知道这个池是如何管理的。如果应用程序中使用了大量的 String 文字,(我理解 String builder 应该在修改如追加,替换操作更多时使用)然后 Pool 通过不一次又一次地重新创建新的 String 对象来增强应用程序的性能但是使用池中存在的相同对象,这是可能的,因为字符串是不可变的并且这样做没有不良影响。

我的问题是这个 String Pool 是如何管理的。如果某些 'k' 字符串的频率很高,并且可能很少有其他字符串对象一旦创建就不会再次使用。可能使用了其他更新的字符串文字。

在这种情况下,字符串池的行为类似于 LRU 缓存,持有 对最新使用的文字的引用并删除旧的不 使用池中的字符串 ?

字符串池是否有大小,或者我们可以在我们的应用程序中控制它吗?

编辑:

通常我们会为我们实现的自定义对象池指定大小。我想知道为什么 Sting Pools 没有像 LRU 这样的功能。这可能是一个功能。在大字符串的情况下也不会有问题。但我觉得它的实现方式是这样的,但我只是想知道为什么它不存在,我的意思是它不存在是出于某种正当理由,拥有这个功能会导致一些不良影响。如果有人能阐明这些不良影响,那就太好了。

字符串池不是 LRU 缓存,因为除非进行 GC,否则条目不会被取出。

有两种方法可以获取字符串池中的条目。字符串文字会自动进入那里,并且可以使用 String.intern() 添加新条目,除非 String 已经存在于池中,在这种情况下会返回对它的引用。

垃圾收集,如果没有更多对它们的引用,这对于字符串文字(例如字符串常量)来说可能比 intern()ed.

实现在 Java 6 和 Java 8 之间(甚至在次要版本之间)发生了很大变化。字符串池的默认大小显然是 1009,但可以使用 -XX:StringTableSize=N(自 Java 7 起)参数更改。此大小是内部散列 table 的 table 大小,因此如果您使用大量 intern()(对于字符串文字,它应该足够),可以将其调整得更高。大小仅影响 intern() 调用的速度,而不影响您可以实习的字符串数量。

基本上,除非您大量使用 intern()(大概是有充分的理由),否则几乎没有理由担心字符串池。特别是因为它不再存储在 PermGen 中,所以它不能再很容易地导致 OutOfMemoryErrors

Source.