美文网首页
运行时常量池

运行时常量池

作者: zhengaoly | 来源:发表于2023-05-25 16:37 被阅读0次

运行时常量池

概念: 属于方法区的一部分 Class 文件中含有常量池表(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容加载之后放到方法区的运行时常量池中。

(1)Class 常量池 (又称常量池) : 主要用于存放两大类常量: 字面量(Literal) 和符号引用量(Symbolic References)。

字面量相当于 Java 语言层面常量的概念, 如文本字符串,声明为 final 的常量值等;

符号引用则属于编译原理方面的概念,包括了三种类型的常量: 类和接口的全限定名、字段名称和描述符、方法名称和描述符。

image.png

(2)运行时常量池: 当类加载到内存中后,jvm 会将 class 常量池中的内容存放到运行时常量中。经过解析(resolve)之后,把符号引用替换为直接引用,解析的过程去查询全局字符串池,也就是 StringTable,来保证运行时常量池所引用的字符串与全剧字符串池中所引用的一致。

(3)字符串常量池(String 常量池,串池,StringTable):类似的 Integer、Long 常量池,属于运行时常量池的一部分(VM 中有且只有一个,被所有类共享),目的是为了分担运行时常量池的工作。

JDK1.8 之后常量池在 元空间中属于本地内存,但 StringTable 在堆 heap 中

image.png

特点

动态性: 相对于 Class 文件的常量池来说,具有动态性, 并非预置入 Class 文件中常量池的内容才能进行方法区的运行时常量池,在运行期间也是可以将新的常量放入池中,例如 String 的 intern() 方法。

运行时常量池时方法区的一部分,也会存在 OutOfMemoryError 异常,但是由于 JDK1.8 后的方法区存放在元空间中,所以不容易出现 OutOfMemoryError 异常。

Demo:

public class Demo04 {

public static void main(String[] args) {

String s1 = "a";

String s2 = "b";

String s3 = "a" + "b";//S3 在编译时期就确定了结果为 “ab”(编译优化)

String s4 = "ab";

String s5 = s1 + s2;

System.out.println(s3 == s4);

System.out.println(s3 == s5);

System.out.println(s4 == s5);

}

}

结果:true false false

String 比较对象时比较的是地址。

使用 javap 反编译后

image.png image.png

可以看到

image.png

s3 与 s4 这些都是从常量池的 #11 中取的 ab 地址是同一个

后面的使用 StringBuilder 的 append 方法拼接。StringBuilder 是个对象,存在堆中与常量池的地址不同。

同样思考:

String s1 = new String(“a”)+ new String(“b”);

String s2 = s1.intern();

String s3=”ab”;

s1==s2

s1==s3

s2==”ab”

的结果

总结:

(1) 常量池中的字符串仅仅是个符号, 第一次用到时才会变为对象。

(2) 利用串池机制,优化重复创建字符串。

(3) 字符串变量拼接原理 StringBuilder append(JDK1.8)。

(4) 字符串常量拼接原理时编译优化。

(5) 可以使用 intern 方法,主动将串池中还没放入的字符串对象放入串池中。

相关文章

  • 细说Java常量池

      Java中的常量池有:class常量池、运行时常量池、String常量池。 为什么要使用常量池?   避免频繁...

  • 类常量池和运行时常量池的区别

    首先常量池分为类编译后的常量池和运行时常量池类的常量池为类编译后生成的 Constant pool:在代码运行时会...

  • 字符串常量池

    静态常量池,运行期常量池,字符串常量池 静态常量池 运行时常量池 字符串常量池 问题 结果: 验证new Stri...

  • JVM-常量池

    JVM-常量池 JVM常量池分为 Class文件常量池 运行时常量池 全局字符串常量池 基本类型包装类对象常量池 ...

  • Java 内存—常量池

    Java中的常量池分为两种型态: 静态常量池 运行时常量池 静态常量池 所谓静态常量池是指class文件中的常量池...

  • 你对常量池够了解吗

    在 java 中,常量池分为以下三种: class 常量池 字符串常量池 运行时常量池 一、class 常量池 1...

  • p4-equals系列:jdk1.6中,JVM字符串常量池在哪里

    在jdk 1.6及以前,字符串常量池是属于运行时常量池的,运行时常量池属于方法区,所以可以说字符串常量池位于方法区...

  • 彻底弄懂java中的常量池

    JVM有几种常量池 主要分为: Class文件常量池、运行时常量池,全局字符串常量池,以及基本类型包装类对象常量池...

  • 常量池

    Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。 静态常量池 : *.class文件中的常量池,...

  • 【JAVA基础】常量池、字符串字面量、JAVA编译

    1.常量池的概念 分为两大类:静态常量池和运行时常量池。 class文件静态常量池即class文件中的常量池, 指...

网友评论

      本文标题:运行时常量池

      本文链接:https://www.haomeiwen.com/subject/jtphedtx.html