【问题标题】:New String Object Creation - Allocate memory in Normal Memory and String Constant Pool? Both?创建新字符串对象 - 在普通内存和字符串常量池中分配内存?两个都?
【发布时间】:2017-10-18 23:32:21
【问题描述】:
String s = new String("abc");

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

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

这背后的一些原因?

【问题讨论】:

    标签: string memory-management jvm


    【解决方案1】:

    没有“普通内存”和“池内存”之类的东西。

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

    在较旧的 JVM 中,为字符串 literals 创建的实例被放置在一个特殊的内存区域中,以降低被垃圾收集的可能性。由于那个称为永久代的内存区域有一些缺点,因此在 Java 8 中放弃了该策略并删除了该内存区域。这种旧行为可能会造成一些混乱。但是,池引用的字符串从来都不需要位于该内存区域中。

    除此之外,尚不清楚您的问题的目标是什么。您已编写代码请求 Java 创建两个不同的 String 实例,Java 会这样做。它这样做的原因,是因为你告诉了它。

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

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

    最后,您有两个具有相同内容的实例,正如您所要求的,它们都指向同一个数组(从 Java 7u6 开始),因此对于两个字符串,单个数组显然不能位于不同的内存区域。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      • 2013-04-15
      • 1970-01-01
      • 2020-06-27
      • 2014-09-14
      • 2011-03-22
      相关资源
      最近更新 更多