字符串常量池

  • 字符串常量池是JVM为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
  • 如果要使用的字符串已经存在于字符串常量池中,JVM会直接返回该字符串的引用,而不是创建一个新的字符串对象。

String s1 = new String("abc");这句话创建了几个字符串对象?

  • 1个或2个

  • 字符串常量池中不存在"abc":会创建2个字符串对象。一个在字符串常量池中,由ldc(load constant)指令触发创建。一个在堆中,由new String()创建,并使用常量池中的"abc"进行初始化。

  • 字符串常量池中已存在"abc":会创建1个字符串对象。该对象在堆中,由new String()创建,并使用常量池中的"abc"进行初始化。

  • ldc (load constant) 指令

    • ldc指令的确是从常量池中加载各种类型的常量,包括字符串常量、整数常量、浮点数常量,甚至类引用等。对于字符串常量,ldc 指令的行为如下:
      • 从常量池加载字符串:ldc首先检查字符串常量池中是否已经有内容相同的字符串对象。
      • 复用已有字符串对象:如果字符串常量池中已经存在内容相同的字符串对象,ldc 会将该对象的引用加载到操作数栈上。
      • 没有则创建新对象并加入常量池:如果字符串常量池中没有相同内容的字符串对象,JVM 会在常量池中创建一个新的字符串对象,并将其引用加载到操作数栈中。