JVM|JAVA中常量池、运行时常量池、字符串常量池区别

JAVA中静态常量池、运行时常量池、字符串常量池区别看上去很相近的概念容易混淆,区分如下(注意英文单词的区别)

  • 静态常量池(Constant Pool)
其实叫“Class文件常量池”比较贴切,就是磁盘中class文件中Constant Pool列表。 可以使用javap命令查看class文件(如下图)会列出class文件中的常量池。
JVM|JAVA中常量池、运行时常量池、字符串常量池区别
文章图片

  • 运行时常量池(Run-time Constant Pool)
在内存中的常量池,既从Class文件加载后,将其常量数据放在内存中。具体而言是放在内存方法区Method Area中(Java7及以前为永久代,Java8及以后为MetaSpace元空间)。
通常,再Run-time Constant Pool中除了保存来自class文件中的常量池数据(既字面符号引用),还会保存由符号引用翻译得到的直接引用。
可以通过HSDB等工具查看内存各个数据,其中可以通过查看内存中Class的Constant pool就是Run-time Constant Pool。

  • 字符串常量池(StringTable)
【JVM|JAVA中常量池、运行时常量池、字符串常量池区别】这个翻译为“String类型常量表”更合适,它存储以双引号包住的String字符串。通过StringTable可以实现相同的String字符串共享。在Java 8,StringTable是存放在内存堆中。
注意区分:上面的Constant Pool是存放:所有字面量内容,这里的字面量是远多于String的,如上图的Constant Pool(既Constant Pool是各种常量等字面量的合集,而StringTable仅与java.lang.String有关。两者是不同的东西。
HotSpot VM里,记录interned string的一个全局表叫做StringTable,它本质上就是个HashTable。常量表存储以双引号包住的String对象的地址引用,而不是String对象本身。具体见另一文章《JVM中字符串常量池StringTable在内存中形式分析》
总上:静态常量池和运行时常量池两者关系十分密切;而字符串常量池(StringTable)是另一个东西。从英文上看名字也可看出差异远近。

    推荐阅读