新的字符串对象创建 - 在正常内存和字符串常量池中分配内存?都?

时间:2017-05-19 00:54:20

标签: string memory-management jvm

String s = new String("abc");

当我们使用new关键字时,Java将在普通(非池)内存中创建一个新的String对象,s将引用它。此外,文字“abc”将被放置在池中。

我在认证书中找到了这些信息。我对此感到好奇,JVM在普通内存中添加“abc”后在String Constant Pool中添加“abc”,那么为什么它在普通内存中创建“abc”?然而,它可以直接在String Constant Pool中分配空间吗?

背后的一些原因?

1 个答案:

答案 0 :(得分:1)

没有“正常记忆”和“池记忆”这样的东西。

所有String个实例都存在于堆上,根据定义,它是包含所有Java对象的内存。有一个字符串池,它基本上是一种哈希映射,包含引用到实例。 String实例不需要在特殊的内存区域中,可由字符串池引用。向池中添加字符串并不意味着任何内存移动。

在较旧的JVM中,为字符串文字创建的实例被放入一个特殊的内存区域,以适应垃圾收集的可能性较低。由于该内存区域(称为永久生成)存在一些缺点,因此放弃了此策略并在Java 8中删除了内存区域。这种旧行为可能会造成一些混淆。但是对于池中引用的字符串来说,它永远不需要在该内存区域中。

除此之外,目前还不清楚你的问题在哪里。您编写了代码,要求Java创建两个不同的String实例,Java将这样做。之所以如此,是因为你告诉过它。

如果您真的想深入了解技术细节,那么您的代码会发生什么:

  • 首先,为您的String请求创建未初始化的new String(…)实例
  • 然后,创建String文字的"abc"实例并添加到池中(除非池中已包含该内容的字符串)
  • 最后,调用第一步创建的String实例的构造函数,第二步的String实例作为参数
    • 在构造函数中,引用char[]数组将被复制

最后,您有两个具有相同内容的实例,如您所请求的,都指向同一个数组(自Java 7u6起),因此单个数组显然不能位于两个字符串的不同内存区域中。