gpt4 book ai didi

Java:为什么只为字符串值维护常量池?

转载 作者:搜寻专家 更新时间:2023-10-30 20:01:56 24 4
gpt4 key购买 nike

我的问题是关于 java 实习和常量池。

Java 为 java.lang.String 维护了一个常量池,以巧妙地使用 JVM 内存,为此 java.lang.String 是不可变的。 那么,为什么 java 不维护其他不可变类型(例如 Long、Integer、Char、Short)的常量池?那不是也可以节省内存吗?

我知道整数值范围 [-127, 127] 是汇集的,但我不明白选择此范围的原因。

这是我编写的测试代码,用于测试其他不可变数据类型的池化。

public class PoolTest {

public static void main(String... args) {

// Pooling of Integer [-127, 127]
Integer x = 127, y = 127;
System.out.println("Integer:" + (x == y)); // prints true
x = 129;
y = 129;
System.out.println("Integer:" + (x == y)); // prints false

// Apparent pooling of short [-127, 127]
Short i = 127, j = 127;
System.out.println("Short: " + (i == j)); // prints true
i = 128;
j = 128;
System.out.println("Short: " + (i == j)); // prints false

// No pooling of long values
Long k = 10L, l = 10L;
System.out.println("Long: " + (i == j)); // prints false
k = 128L;
l = 128L;
System.out.println("Long: " + (i == j)); // prints false

}
}

最佳答案

常量池的目的是通过保留多个常量副本来减少所需的内存开销。在 String 的情况下,JVM 本质上需要为每个单独可区分的常量保留一些对象,Java 规范基本上说 JVM 应该删除重复的 String 对象加载类时。通过 intern 手动将 String 放入池中的能力很便宜,并且允许程序员识别将在整个生命周期中存在的特定值(例如属性)程序并告诉 JVM 将它们放在正常垃圾收集之外。

另一方面,出于以下几个原因,合并数字常量没有多大意义:

  • 大多数特定数字从未在给定程序的代码中使用过。
  • 当代码中使用数字时,将它们作为直接操作码值嵌入代码中比尝试将它们集中起来在内存方面成本更低。请注意,即使是空的 String 也带有一个 char[],一个 int 代表它的长度,另一个代表它的 hashCode。相比之下,对于数字,最多需要八个立即字节。
  • 从最近的 Java 版本开始,ByteShortInteger 对象从 -128 到 127( 为 0 到 127 Character) 被预缓存是出于性能原因,而不是为了节省内存。之所以选择这个范围,大概是因为这是一个带符号字节的范围,它将涵盖大量常见用途,而尝试预缓存大量值是不切实际的。

请记住,关于实习的规则早在 Java 5 中引入自动装箱和泛型类型之前就已制定,这显着扩大了包装类的随意使用范围。使用量的增加导致 Sun 将这些通用值添加到常量池中。

关于Java:为什么只为字符串值维护常量池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20394116/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com