在Java中,计算对象默认的hash值的方法在synchronizer.cpp文件中。对象的hash是在第一次使用时,即首次调用hashCode方法时进行计算,并将hash值存储在对象的Mark Word中。
类java.lang.Object#hashCode() 方法是native,最终调用到ObjectSynchronizer::FastHashCode函数获取hash值,下图为获取对象hash值的基本流程。
结合此流程图和代码注释读FastHashCode函数,应该很容易看懂,本文暂不详细讲解。
FastHashCode在计算hash值时,有两个核心计算hash值的函数,一个是get_next_hash()函数,一个是hash()函数.
synchronizer.cpp中的get_next_hash方法用于计算新的hash值。
get_next_hash函数会根据传给JVM的参数-XX:hashCode=n来选择使用哪种方法生成对象的hashcode:
- hashCode=0,hash值为系统生成的随机数
- hashCode=1,hash值为对对象地址做移位和异或操作
- hashCode=2,所有的hash值都等于1
- hashCode=3,hash的值为一个自增序列的值
- hashCode=4,hash值为此对象地址
- hashCode=others, 使用Xorshift随机数生成器,Xorshift随机数生成器总体性能非常好。Xorshift原理
另外一种是hash()函数。其先获取该对象的Mark Word,然后对Mark Word对象的的地址做位移和逻辑与操作,以结果作为hash值。