2016-06-21 53 views
3

产生双引号,我尝试执行下面的代码行生成。我的理解是#1和#2都应该在字符串池中生成字符串,因此在执行过程中不应该有任何区别,但是当我分析堆转储时,如果在字符串池中生成intern()字符串(可以通过有限数量的字符串对象来解释),但是在堆上生成#1字符串的情况下(因为堆转储中存在大量字符串对象),并且系统比以前的情况快。有人可以解释为什么它是这样吗?我正在使用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

+0

字符串仅当它的可用池接到一个字符串池参考否则其创造堆的字符串。 – Nir

+0

在内环它应产生的第一执行1000唯一字符串字符串0 .... ....到字符串999。在此之后,应在内部循环的所有后续执行作为第一字符串执行期间创建的不是程序使用的参考参考应该在字符串池中可用? – Vyas

回答

1

如果创建一个字符串没有实习它,它只是去堆。所以可以有多个相同字符串的副本。如果您在字符串中实习,每个相等类将只有一个字符串。

为相同的j多次创建字符串"String" + j更多的内存消耗,没有实习字符串。

实习节省内存,但因为每个字符串在某种HashSet的召开和创建一个字符串意味着仰视,如果它已经存在于HashSet的存在还可以减慢程序。

注:某些字符串自动扣留,例如源代码中的字符串文字。

+1

你是否将字符串创建为String s =“Nothing”;不会在字符串池中自动创建?我的理解是,如果一个字符串是使用new运算符创建的(String s = new String(“nothing”)),它将在堆上创建,并且如果使用双引号创建字符串(String s =“nothing”),它将由默认情况下在permgen空间的字符串池中创建。使用intern()调用字符串可以将字符串从堆移到字符串池。如果事情是不正确的在我的理解 – Vyas

+1

最多据我所知,一个字符串仅自动,如果它是一个编译时间常数(其中“串” + j不)拘留请指正。如果我错了,请指点适当的来源。 –

+0

这是我没有意识到一个字符串需要编译时间常量才能在字符串池中生成。感谢您的帮助。 – Vyas