3

我试图了解字符串池的工作原理。我浏览了许多站点,最后我现在更加困惑。让我在这里放下我的疑惑。有人帮助我理解它们。

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

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

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

提前致谢。

4

3 回答 3

4

字符串管理方式的实际实现在 Java 中不应该是重要的,除了以下保证:

  1. 字符串 x = "你好"; 字符串 y = "你好"; // 保证 x == y
  2. 字符串 x = "你好"; 字符串 y = new String("hi"); // 不保证 == 尽管有可能 !=
  3. 字符串 x = new String("hi"); 字符串 y = new String("hi"); // 保证 != 但 x.equals(y)
  4. 字符串 x = "你好"; String y = new String("hi").intern(); // 保证 x == y

这些是字符串的规则......

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

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

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

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

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

当我查看 String 的源代码时,我发现代码在很大程度上依赖于 String 的不可变性。因此,例如, new String(new String("hi")); 只创建一个 char 数组,并且在两个 String 实例中共享。(无论如何内部实例都会被GC)。

于 2013-10-24T18:49:08.747 回答
0

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

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

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

但,

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

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

于 2014-05-29T11:21:23.780 回答
0

1.String pool不是STACK,也不是HEAP!这是方法区!字符串池属于常量池。因为我们都知道,CONSTANT是一个不能改变的值,给定一个常量池的目的是为了加快程序的速度。在您的 Class 文件中,例如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 pool是否存在String的对象。如果是,则将String对象返回给用户,不会重新创建新的String对象。如果 String pool 没有 String 对象,JVM 会在 HEAP 中创建一个新对象并返回给用户,同时 JVM 会将其放入 String pool。

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   
于 2013-10-24T19:12:04.870 回答