lam*_*y.x 27 java memory string equality
请考虑以下类:
class Eq {
public static void main(String[] args) {
System.out.println("" == ".".substring(1));
}
}
Run Code Online (Sandbox Code Playgroud)
该示例应该显示内存中可能存在空字符串的多个副本。我仍然有一个旧的 OpenJDK 11,程序false按预期输出。在 OpenJDK 15 下,程序输出true. 为类文件生成的字节码看起来相似(即使它们的寄存器值不同):
爪哇11:
public static void main(java.lang.String[]);
Code:
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String
5: ldc #15 // String .
7: iconst_1
8: invokevirtual #17 // Method java/lang/String.substring:(I)Ljava/lang/String;
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #23 // Method java/io/PrintStream.println:(Z)V
22: return
Run Code Online (Sandbox Code Playgroud)
爪哇 15:
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String
5: ldc #4 // String .
7: iconst_1
8: invokevirtual #5 // Method java/lang/String.substring:(I)Ljava/lang/String;
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V
22: return
Run Code Online (Sandbox Code Playgroud)
我试图通过阅读“.”来排除静态编译器优化。来自标准输入,但这不会改变结果。我试图禁用 JIT via-Djava.compiler=NONE并尝试通过调整字符串表大小-XX:StringTableSize=100000。我现在有以下问题:
我认为只是策略来解决如何找到不回答问题的行为的原因也可能很有趣。
And*_*eas 33
这在JDK 15 发行说明 中提到。
根据 JDK-8240094 的要求对其进行了更改:
JDK-8240094:优化空子串处理
String.substring""在某些情况下返回,但可以改进以在子字符串长度为零的所有情况下都这样做。
有关的:
JDK-8240225:优化空子串处理
优化
String.substring和相关操作,如stripLeading,stripTrailing避免重复创建新的空字符串。
子任务:
JDK-8251556:发行说明:优化的空子字符串处理
的实施
String.substring和相关方法stripLeading和stripTrailing在此版本中已更改为避免冗余创建一个新的空字符串。这可能会影响依赖于未指定行为和空子字符串标识的代码。