使用双引号生成的字符串未在字符串池中生成

时间:2016-06-21 11:38:03

标签: java string

我尝试执行下面的代码行。我的理解是#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

的情况下转储对象截图

string

1 个答案:

答案 0 :(得分:1)

如果你创建一个没有实习的字符串,它就会进入堆。因此可以存在多个相等字符串的副本。如果你实习字符串,每个相等类只有一个字符串。

为同一个"String" + j多次创建字符串j,在没有实现字符串的情况下会占用大量内存。

实习可以节省内存,但它也可以减慢程序的速度,因为每个字符串都保存在某种HashSet中,并且创建一个字符串意味着查看它是否已存在于该HashSet中。

注意:某些字符串会自动实现,例如源代码中的字符串文字。