Java:为什么只为String值维护常量池? [英] Java: Why is constant pool maintained only for String values ?

查看:164
本文介绍了Java:为什么只为String值维护常量池?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My question is about java interning and constant pools.

Java为 java.lang.String ,巧妙地使用JVM内存,并且这样做java.lang.String是不可变的。 那么为什么java不维护其他不可变类型的常量池,例如Long,Integer,Char,Short?这不会节省内存吗?

Java maintains a a constants pool for java.lang.String, to use JVM memory cleverly, and to do so java.lang.String is made immutable. So why doesn't java maintain constant pools of other immutable types, such as Long, Integer, Char, Short ? Wouldn't that save memory too ?

我知道整数被汇总到了值范围[-127,127],尽管我不明白选择这个范围的原因。

I am aware of the fact that Integers are pooled for value range [-127, 127], though I do not understand the reason for choosing this range.

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

Here's a test code I wrote to test pooling of other immutable data types.

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 类加载时的对象。通过实习生在池中手动放置 String 的功能很便宜,并且允许程序员识别特定值(例如属于程序生命周期,并告诉JVM将它们放在正常的垃圾收集方式之外。

The purpose of a constant pool is to reduce the memory overhead required by keeping multiple copies of constants. In the case of Strings, the JVM is inherently required to keep some object around for each individually distinguishable constant, and the Java spec basically says that the JVM should deduplicate String objects when class loading. The ability to manually place Strings in the pool via intern is inexpensive and allows programmers to identify particular values (such as properties) that are going to be around for the life of the program and tell the JVM to put them out of the way of normal garbage collection.

汇集数字常量,打开另一方面,由于以下几个原因,没有多大意义:

Pooling numeric constants, on the other hand, doesn't make a lot of sense, for a few reasons:


  • 大多数特定数字从未用过给出程序的代码。

  • 在代码中使用数字时,将它们作为立即操作码值嵌入代码中,在内存方面比尝试汇集它们要便宜。请注意,即使空字符串也带有 char [] int 表示其长度,另一个表示 hashCode 。相比之下,对于一个数字,最多需要八个立即字节。

  • 从最近的Java版本开始,字节整数 -128到127之间的对象( 0 <127 )由于性能原因而被预先缓存,而不是为了节省内存。这个范围可能是因为这是一个有符号字节的范围,它将涵盖大量常见用途,而尝试预先处理大量值是不切实际的。

  • Most particular numbers aren't ever used in a given program's code.
  • When numbers are used in code, embedding them in the code as immediate opcode values is less expensive in terms of memory than trying to pool them. Note that even the empty String carries around a char[], an int for its length, and another for its hashCode. For a number, by contrast, a maximum of eight immediate bytes is required.
  • As of recent Java versions, Byte, Short, and Integer objects from -128 to 127 (0 to 127 for Character) are precached for performance reasons, not to save memory. This range was presumably chosen because this is the ranged of a signed byte, and it will cover a large number of common uses, while it would be impractical to try to precache a very large number of values.

作为一个注释,请记住,在Java 5中引入自动装箱和泛型类型之前很久就已经制定了关于实习的规则,这大大扩展了包装类的数量随便使用。使用量的增加导致Sun将这些常用值添加到常量池中。

As a note, keep in mind that the rules about interning were made long before the introduction of autoboxing and generic types in Java 5, which significantly expanded how much the wrapper classes were casually used. This increase in use led Sun to add those common values to a constant pool.

这篇关于Java:为什么只为String值维护常量池?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆