我想了解字符串池是如何工作的。我浏览了很多网站,最后我现在更加困惑了。让我在这里放下我的疑惑。有人帮助我理解它们。
1) 字符串池存在于何处?在堆还是在方法区?
2) String s = "Hello world";
- 这足以创建一个字符串。由于字符串是不可变的,一旦创建字符串就不能更改,那么创建字符串需要什么
String s = new String(“Hello World”)
?
虽然它强制 JVM 在堆中创建一个新的 String 对象而不是 String 池。但是强制 JVM 为新的 String 对象需要什么??
3) 何时以及如何对字符串进行垃圾回收?
提前致谢。
最佳答案
字符串管理的实际实现在 Java 中不应该是重要的,除了保证:
- 字符串 x = "你好";字符串 y = "嗨";//保证 x == y
- 字符串 x = "你好"; String y = new String("嗨");//不保证 == 尽管可能 !=
- String x = new String("hi"); String y = new String("嗨");//保证 != 但是 x.equals(y)
- 字符串 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 实例,我只能想到一个地方这样做才有意义,那就是如果有人想将结果对象用作同步锁。这在调试东西时很有意义……但意义不大。您必须使用“new”,这样您就不会无意中使用与其他一些代码相同的 String 对象来进行同步。
在一般的 Java 编码实践中,我通常没有看到人们使用 new String ("...")
。现实情况是,在大多数情况下,人们只是简单地使用字符串连接运算符等。但是,这并不意味着执行 new String(...)
当我查看 String 的源代码时,我发现代码在很大程度上依赖于不可变的 String。因此,例如, new String(new String("hi"));只创建一个 char 数组,并在两个 String 实例中共享。 (无论如何,内部实例都会被 GC)。
关于Java String pool相关疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19573990/