据我所知,如果在String池中找到String,则intern方法应该从String池返回String,否则将在String池中添加new string object
并返回此String的引用。
String s = "a";
s = "b";
String str = new String("a").intern();
在这种情况下会发生什么......是否存在两种情况
String str = new String("a").intern();
执行str会引用此“a”或“a”从未符合垃圾回收的条件?
答案 0 :(得分:3)
这在不同的JVM中是不同的。例如,
OpenJDK / Hotspot Java 6:字符串文字在PermGen和AFAIK中,只在Full GC上清理(不仅仅是终身空间的主要集合)
OpenJDK / Hotspot Java 7:字符串文字在Heap中,可以随时收集它们,但我怀疑它们是由代码中使用的PermGen持有的。
OpenJDK / Hotspot Java 8:没有PermGen所以即使由现在位于堆中的Classes保存,也应该更自由地清理字符串。
1)只有一个字符串文字,并且在没有引用它之前它不会被GC,也可能在cde中,这可能是在ClassLoader卸载时,如果有的话。
2)你创建的第一个"a"
和第二个"a"
以及第三个可能是不同的字符串,如果它们之间有GC。
答案 1 :(得分:2)
当Java包含的类超出范围时,Java规范不会正式禁止String
常量的垃圾收集,但是any two String
literals with identical contents must refer to the same String
object,String#intern()
的返回值必须是同一个对象这将由具有相同内容的文字引用。
给定的JVM是否实际上从运行时常量池中垃圾收集String
个对象是一个实现细节,但给定这些要求的String
个实例的可达性规则是{{1如果任何可到达的变量包含对它的引用或者加载了任何具有该文字的类,则可以在常量池中访问它。
在您的特定情况下,String
文字String
符合以下条件进行垃圾回收:
"a"
和s
的第一个值,它引用同一个对象,它位于常量池中)和str
的{{1}}常量的所有类。答案 2 :(得分:2)
答案 3 :(得分:0)
正如其他人所提到的,行为是一个实现细节。找到的一种方法是仅使用WeakReference然后force a garbage collection引用字符串,并查看WeakReference是否已被清除。
以下是一些示例代码:
// Only keep a weak reference to a
String str = "a";
WeakReference<String> strRef = new WeakReference<String>(str);
str = null;
// Attempt to force GC
Object obj = new Object();
WeakReference<Object> ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get() != null) {
System.gc();
}
// Wait a bit a second to make sure GC has actually run
Thread.sleep(1000);
// Print the result
if (strRef.get() == null) {
System.out.println("String \"a\" has been garbage collected");
} else {
System.out.println("String \"a\" has not been garbage collected");
}
在使用JavaSE-1.7的我的机器上,String不是垃圾回收。