【问题标题】:String pool vs Constant pool字符串池与常量池
【发布时间】:2014-06-08 18:52:00
【问题描述】:

我们看下面的代码sn-p:

  String s1 = "Hello";
  String s2 = "Hello"; 

由于实习,两个变量都引用同一个对象。由于字符串是不可变的,因此只创建一个对象,并且都引用同一个对象。

constant pool 也是一个东西,它包含在一个类中声明的所有常量(整数、字符串等)。它特定于每个类。

 System.out.println("Hello");  // I believe this Hello is different from above.

问题:

  1. string pool是指常量池中常量字符串对象的池吗?
  2. 如果是,字符串池是在整个应用程序中通用还是特定于某个类?

【问题讨论】:

标签: java string jvm constants


【解决方案1】:

我的问题是,

  1. 字符串池是指常量池中常量字符串对象的池吗?

没有。

“常量池”是指类文件中特殊格式的字节集合,对 Java 类加载器有意义。其中的“字符串”是serialized,它们不是Java 对象。常量也有很多种,其中不只是字符串。

Chapter 4.4 the constant pool table

Java 虚拟机指令不依赖于类、接口、类实例或数组的运行时布局。相反,指令引用constant_pool 表中的符号信息。

相比之下,“字符串池”在运行时使用(不仅仅是在类加载期间),只包含字符串,而字符串池中的“字符串”是java对象。 “字符串池”是一个线程安全的弱映射,从 java.lang.String 实例到 java.lang.String 实例用于实习字符串。

Chapter 3.10.5. String Literals

字符串文字是对 String 类实例的引用(第 4.3.1 节、第 4.3.3 节)。

此外,字符串文字总是引用类String相同 实例。这是因为字符串字面量 - 或者更一般地说,作为常量表达式值的字符串(第 15.28 节) - 是“内部的”,以便使用 String.intern 方法共享唯一实例。

【讨论】:

  • 这个字符串池存储在哪里?作为链接java-performance.info/string-intern-in-java-6-7-8 声称实习字符串存储在堆中。那么它是与其他对象所在的堆相同还是不同?任何指向 javadocs 或 java 规范的链接将不胜感激。
  • @nanosoft,使用分代垃圾收集器,新对象在nursery 中分配,但实习字符串通常是长期存在的,因此实现可以跳过由类加载器分配的字符串的托儿所。 JVM 是否这样做是一个实现决定,并且不受 Java 虚拟机规范 的强制要求。 Java Language规范是Java规范的另一半,但在内存管理问题上主要委托给JVM规范。
  • 你确定String Pool是一个weak map吗? JVM 规范中没有任何信息可以声称这一点。你是怎么知道的?您能否提供一些对 openjdk 源代码的参考或任何其他可以证明这一点的官方参考?
【解决方案2】:

只有一个字符串池,所有的字符串字面量都会被自动interned。
此外,还有其他用于自动装箱等的池。

常量池是为类放置这些文字的地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多