【问题标题】:Why same integer value have different memory address in Java? [duplicate]为什么Java中相同的整数值具有不同的内存地址? [复制]
【发布时间】:2012-08-06 14:36:46
【问题描述】:

今天是我第一次尝试 Java 语言。当我尝试这段代码时,感觉很奇怪:

int a =500;
System.out.println(System.identityHashCode(500));
System.out.println(System.identityHashCode(500));
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(a));

所有这些结果都是不同的。但是当我把 500 改成 50 时,结果是一样的。

为什么会这样?

【问题讨论】:

  • @Tichodroma 这是怎么复制的?没有涉及字符串,也没有整数......但也许我对这件事的理解不够好,因为我对代码的结果感到困惑。 (我可以确认)
  • @brimborium 您是否阅读了该问题的已接受答案?寻找500
  • @Tichodroma 是的。我知道这是密切相关的......但我认为这个问题已经很好地说明并且仍然不是重复。

标签: java memory


【解决方案1】:

但是当我把 500 改成 50 时,结果还是一样。

自动装箱缓存原始到对象的转换。较小的值得到相同的对象,较大的值不会。

注意:虽然始终缓存 -128 和 127 之间的值,但可以缓存更高的值,具体取决于命令行设置。有关详细信息,请参阅Integer 的来源。

这也称为Flyweight Pattern


您可以设置整数缓存的最大大小

-Djava.lang.Integer.IntegerCache.high=NNNN
-XX:AutoBoxCacheMax=NNNN
-XX:+AggressiveOpts  // sets it higher depending on the version e.g. 10000

http://martykopka.blogspot.co.uk/2010/07/all-about-java-integer-cache.html

http://www.javaspecialists.eu/archive/Issue191.html

我觉得很奇怪

我知道你读这个问题的意思。 ;)

【讨论】:

  • 不知道命令行设置;你能详细说明一下吗?我只看到Integer.valueOf(int i) 使用的private static class IntegerCache,这让我想起了memoization
  • @trashgod 至少有三个选项可以改变整数缓存的上限。添加了示例和链接。
  • @trashgod Flyweight 模式和记忆有相似之处。两者都试图通过使用缓存来减少工作。
  • 好的,我现在明白了:IntegerCache 是数据结构,valueOf() 是回收缓存实例的静态工厂。顺便说一句,早先 +1。
  • 它不会像这样回收对象,因为它们永远不会返回。它只是将它们分发出去。它可以做到这一点,因为它们是不可变的。
【解决方案2】:

它缓存了int的值-128和127(含),所以它会在那个范围内引用内存中的同一个实例

当您将原始值传递给(此处为10)时

System.identityHashCode(10);

它将其自动装箱为Integer 对象,然后使用整数类的valueOf() 方法进行转换

举例

Integer a = 10;

将转换为内部使用valueOf()

1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

Integer.valueOf() 有缓存实现

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

因此,如果您将值从 -128 传递到 127(含),它将使用缓存版本,如您所见

    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];

另见

【讨论】:

  • +1 另见memoization
  • @trashgod 我将其称为享元模式,因为对象被缓存以减少对象创建开销,而不是存储结果以减少计算时间。
猜你喜欢
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多