我尝试执行下面的代码行。我的理解是#1和#2都应该在String池中生成字符串,因此两个执行都不应该有任何区别,但是当我分析堆转储时,如果intern()字符串是在String池中生成的(可以通过有限数量的字符串对象来解释)但是在#1的情况下,正在Heap上生成字符串(因为堆转储中存在大量字符串对象),并且系统比前一种情况更快地耗尽内存。有人可以解释为什么会这样吗?我使用java 6来执行下面的代码行。
import java.util.LinkedList;
public class LotsOfStrings {
private static final LinkedList<String> LOTS_OF_STRINGS = new LinkedList<String>();
public static void main(String[] args) throws Exception {
int iteration = 0;
while (true) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 1000; j++) {
String s= "String " + j;
LOTS_OF_STRINGS.add(s); // #1
//LOTS_OF_STRINGS.add(new String("String " + j).intern()); //#2
}
}
iteration++;
System.out.println("Survived Iteration: " + iteration);
Thread.sleep(100);
}
}
如果是实习生,将转储对象屏幕截图 intern
在#1
的情况下转储对象截图答案 0 :(得分:1)
如果你创建一个没有实习的字符串,它就会进入堆。因此可以存在多个相等字符串的副本。如果你实习字符串,每个相等类只有一个字符串。
为同一个"String" + j
多次创建字符串j
,在没有实现字符串的情况下会占用大量内存。
实习可以节省内存,但它也可以减慢程序的速度,因为每个字符串都保存在某种HashSet中,并且创建一个字符串意味着查看它是否已存在于该HashSet中。
注意:某些字符串会自动实现,例如源代码中的字符串文字。