Java String pool相关疑惑

标签 java string jvm pool

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

1) 字符串池存在于何处?在堆还是在方法区?

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

3) 何时以及如何对字符串进行垃圾回收?

提前致谢。

最佳答案

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

  1. 字符串 x = "你好";字符串 y = "嗨";//保证 x == y
  2. 字符串 x = "你好"; String y = new String("嗨");//不保证 == 尽管可能 !=
  3. String x = new String("hi"); String y = new String("嗨");//保证 != 但是 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 实例,我只能想到一个地方这样做才有意义,那就是如果有人想将结果对象用作同步锁。这在调试东西时很有意义……但意义不大。您必须使用“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/

相关文章:

java - 我们可以为 JVM 编写插件吗

java - Android - 从没有扩展名的文件中获取 MIME 类型

java - java支持编译时多态吗?

c++ - 返回字符串的静态方法

c - 替换 C 中字符串中所有出现的子字符串

c - 为什么C语言中字符串转十六进制需要用0xff来完成?

Java 对 Runtime.memory() 与 Windows 的物理内存使用历史图的混淆

jvm - PHPStorm/Webstorm 内存增加至 512MB 以上

java - 高枕无忧 - 使用 RestAssured 进行测试时出现操作超时错误。但相同的端点在浏览器中工作正常

java - 我如何将 Long 变量与 null 进行比较