CLR/JVM是否为所有正在运行的.net/java应用程序保留一个单一的实习池?

San*_*box 6 .net c# java string string-interning

以下是MSDN的摘录:

公共语言运行库通过维护一个名为intern pool的表来保存字符串存储,该表包含对在程序中以编程方式声明或创建的每个唯一文字字符串的单个引用.因此,具有特定值的文字字符串实例仅在系统中存在一次.

例如,如果将相同的文字字符串分配给多个变量,则运行时将从实习池中检索对文字字符串的相同引用,并将其分配给每个变量.

Intern方法使用实习池来搜索等于str值的字符串.如果存在此类字符串,则返回其在实习池中的引用.如果该字符串不存在,则将对str的引用添加到实习池中,然后返回该引用.....如果您正在尝试减少应用程序分配的内存总量,请记住,实习字符串有两个不需要的副作用.首先,在公共语言运行时(CLR)终止之前,不太可能释放为被占用的String对象分配的内存.

那么,这是否意味着CLR为所有正在运行的.net应用程序保留一个单一的实习池?示例:如果程序A创建字符串文字"Test",并且如果另一个程序尝试创建另一个字符串文字"Test",则使用相同的副本?同样的问题也适用于JVM.

Chr*_*Wue 2

CLR 为每个实例保留一个内部池。如果您进一步阅读MSDN 链接

如果您尝试减少应用程序分配的内存总量,请记住,驻留字符串会产生两个不需要的副作用。首先,在公共语言运行时 (CLR) 终止之前,为暂存 String 对象分配的内存不太可能被释放。

对于 Java,它也是针对您启动的每个 JVM。

然而根据这篇文章

这个神话与神话 2 的方向相反。有些人认为内化字符串会保留在内存中,直到 JVM 结束。很久以前这可能是正确的,但今天,如果不再引用内化字符串,它们就会被垃圾收集。下面是上面程序的稍加修改的版本。它会不时地清除对内部化字符串的引用。如果您从 jconsole 跟踪程序执行,您将看到 PermGen 空间使用量上下波动,因为垃圾收集器回收未引用的内部化字符串使用的内存。

这意味着在 Java 中,interned 字符串实际上可以被 GC 处理。