【问题标题】:When does the jvm assign hashcode value in the object headerjvm什么时候在对象头中分配hashcode值
【发布时间】:2017-02-23 10:59:50
【问题描述】:

了解到java的object header包含hashcode、gc year、biased lock等信息。然后一个谜题出现在我面前,为了明确地表达我的问题。我举个例子。
代码如下:

public class Demo{
    @Override
    public int hashCode(){
        System.out.println("the hashCode method was called");
        return super.hashCode();
    }

    public static void main(String[] args){
        Demo demo = new Demo();
        System.out.println("after generate an object");
        //
        Set<Demo> set = new HashSet<Demo>();
        set.add(demo);
    }
}

还有输出:

after generate an object
the hashCode method was called

我猜当我们新建一个对象时,jvm 会在对象头中设置 hashcode。但是如果为了生成 hashCode 它应该调用这个对象的 hashCode 方法然而根据输出似乎它没有调用 hashCode 方法 当新的对象。并将值添加到 hashSet 中,调用 hashCode 方法,这正如预期的那样。

所以我的问题是:jvm 什么时候在对象头中分配哈希码值?发生在新建对象的阶段?

  • 如果是。为什么它没有调用hashcode方法,没有这个怎么计算这个对象的hashcode
  • 如果不是。呃……每次调用 invoke hashCode 方法时更新 object header 中的 hashcode 是没有意义的。

【问题讨论】:

    标签: java jvm


    【解决方案1】:
    • JVM不需要调用hashCode方法来初始化对象的标识hashCode。反之亦然:Object.hashCodeSystem.identityHashCode 调用 JVM 来计算或提取之前计算的身份 hashCode。
    • 未指定 JVM 如何生成和存储身​​份 hashCode。不同的 JVM 实现可能会有所不同。
    • HotSpot JVM 在第一次调用 Object.hashCodeSystem.identityHashCode 时计算身份 hashCode 并将其存储在对象头中。随后的调用只是从标头中提取先前计算的值。

    【讨论】:

    • 在对象创建过程中,身份哈希码不是计算并保存在对象头中吗?
    • @Sher10ck 不会。这会显着降低对象分配的性能。
    【解决方案2】:

    我认为您混淆了哈希码和身份哈希码。

    对象的哈希码不会存储在对象头中,而是根据需要通过调用哈希码方法计算得出。在您的示例中调用哈希码是因为您将对象添加到 HashSet

    标识哈希码由 JVM 在创建对象时计算,并作为对象哈希码值的后备服务(除其他外)。即Object.hashcode() 将返回您的对象的身份哈希码。此值在对象的生命周期内不会发生变化。

    更多详情请参阅this question

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      • 2011-11-25
      • 2020-05-16
      • 1970-01-01
      • 2017-09-06
      • 1970-01-01
      相关资源
      最近更新 更多