最近看java虚拟机,书上说 字符串常量池在jdk1.7移除方法区了,但是运行时常量池还是方法区的一部分,那意思是不是字符串常量池 和 运行时常量池 就是两个东西 ?没有关系?那String的intern()方法是往添加到哪个池?
java运行时常量池包括字符串常量池的
常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。
https://blog.csdn.net/Sugar_Rainbow/article/details/68150249
这里解释得很清楚
字符串常量池在编译时固定了,在运行时从中读取的
运行时常量池逻辑上是包含字符串常量池的。
去永久代的过程在JDK7中只进行了一小步。从网上查到的资料来看,确实只将字符串常量池移出永久代,这属于jvm实现上的差异。
到JDK8永久代完全被元空间取代了。
《深入理解Java虚拟机》2.2.6 运行时常量池一节明确说明了Java虚拟机规范对运行时常量池没有做任何细节的要求,不同的提供商按需求实现虚拟机的这一区域。且接下来一段中说明运行时常量池的动态性时,明确提到了String类的intern()方法可以在运行时将新的常量放入运行时常量池,具体来说就是字符串常量池了。
我是这么理解的,java代码编译成class文件后,class文件中存在常量池,其中包含了字面量,字符串直接量,符号引用等。
当把class文件中的一些常量加载到方法区的运行时常量池时,从java7开始,字符串常量使用的是java虚拟机堆上的内存。java6使用的方法区上的内存。
漏写补充:从java7开始,字符串常量池使用的是java虚拟机堆上的内存。java6使用的方法区上的内存。也就是说,java7开始,逻辑上,在方法区中运行时常量池中使用了在堆上的字符串常量池中常量。调用string.intern()还是往字符串常量池中加对象或引用(java7开始能加引用了)(如果该字符串不存在的话)。