Java字符串池相关的疑点

时间:2013-10-24 18:41:08

标签: java string jvm pool

我正在努力理解字符串池是如何工作的。我经历了很多网站,最后我现在更加困惑了。让我在这里放下我的疑虑。有人帮助我理解它们。

1)字符串池在哪里?在堆中还是在方法区域?

2)String s = "Hello world"; - 这就足以创建一个string.Since字符串是不可变的,一旦创建了字符串不能更改,那么创建字符串的需要是什么 String s = new String(“Hello World”)
              虽然它强制JVM在堆中而不是String池中创建一个新的String对象。但是对于新的String对象强制JVM的需求是什么?

3)字符串何时以及如何收集垃圾?

提前致谢。

3 个答案:

答案 0 :(得分:4)

除了保证:

之外,在Java中如何管理字符串的实际实现不应该是重要的。
  1. String x =“hi”;字符串y =“hi”; //保证x == y
  2. String x =“hi”; String y = new String(“hi”); //没有保证==虽然可能!=
  3. String x = new String(“hi”); String y = new String(“hi”); //保证!=但是x.equals(y)
  4. String x =“hi”; String y = new String(“hi”)。intern(); //保证x == y
  5. 这些是Strings的规则......

    过去(这将随Java8而改变),String.intern()和字符串常量(String x = "hi")被分配在内存模型的PermGen空间中。

    因此,它们具有不同的GC机制,即使您有大量的可用堆空间(PermGen通常小于128MB),如果使用String.intern()也可能会耗尽内存。

    使用new String(....)分配的字符串在常规堆上,并且具有标准GC机制。

    至于为什么你/我们使用new String ("...")创建字符串的新实例,我只能想到一个只有这样做才有意义的地方,那就是有人想要使用结果对象作为同步锁。这在调试时可能有意义.....但没有多大意义。您必须使用'new',这样您就不会无意中使用与其他代码相同的String对象进行同步。

    在一般的Java编码实践中,我通常没有看到人们使用new String ("....")。现实情况是,人们在大多数情况下只使用字符串连接运算符等。但是,这并不意味着做new String(...)

    是错误的。

    当我查看String的源代码时,我发现代码在很大程度上依赖于String是不可变的。所以,例如,new String(new String(“hi”));只创建一个char数组,并在两个String实例中共享它。 (无论如何,内部实例将是GC'd。)

答案 1 :(得分:0)

1.String pool不是STACK,也不是HEAP!这是方法区! 字符串池属于常量池。因为我们都知道,CONSTANT是一个无法改变的值,给定一个恒定池的目的是加快程序的速度。在您的类文件中,例如int a = 10, String b = "123450"被视为字符串(您可以在方法中更改它们)。加载类时,JVM会将它们放在一个数组中进行维护。并将此数组放在名为String Pool的METHOD区域中。

2.当您创建String对象时,您可以执行以下操作: String str1 = new String("abc")Stirng str2 = "abc";。它们看起来一样,但JVM以不同的方式处理它们。对于第一个,JVM将在HEAP中创建String对象。并将对象返回给用户。但是对于第二个,JVM将使用String的equals()方法检查String Pool,以检查String池是否存在String的对象。如果是,则将String的对象返回给用户,并且不会重新创建String的新对象。如果String池没有String对象,JVM将在HEAP中创建一个新对象并返回给用户,同时JVM将把它放入String池中。

String str1 = new String("abc"); //jvm creates a String object in Heap.

 //jvm can not find "abc" in String pool  
 //Create a String object in heap,and put it in strings pool   
 //Now heap has two string object.
Stirng str2 = "abc";   

 if(str1 == str2){   
         System.out.println("str1 == str2");   
 }else{   
         System.out.println("str1 != str2");   
 }   
  //Print result is  str1 != str2, because they are different objects in heap

  String str3 = "abc";   

 //Now,jvm realizes String Pool already had “abc” object,because “abc”equals “abc”

  if(str2 == str3){   
         System.out.println("str2 == str3");   
  }else{   
         System.out.println("str2 != str3");   
  }   
 //Print result is str2 == str3  



String str1 = new String("abc"); 

str1 = str1.intern();   


Stirng str2 = "abc";   

 if(str1 == str2){   
         System.out.println("str1 == str2");   
 }else{   
         System.out.println("str1 != str2");   
 }  //Print: str1 == str2   

答案 2 :(得分:0)

字符串池就像一个具有String常量的存储桶。 例如: -

Object a = new Object();
Object b = new Object();

它将在Heap中创建两个新对象。

但是,

String s1 = "abc";
String s2 = "abc";

它只会在String池中创建一个对象,因为它们是常量。