一、identityHashCode怎么生成的?
在JAVA中的hashcode(一)中提到了 identityHashCode(标识哈希码)
,本文继续来看下底层的具体实现。
// java.lang.System.java
public static native int identityHashCode(Object x);
// java.lang.Object.java
public native int hashCode();
java源码中该方法是一个native
标识,具体依赖JVM的实现机制,需要看C++代码了。本文以OpenJDK为例。
这里直接展现生成hash的最终函数get_next_hash
,该函数提供了6
中方法,如下。
- 0、随机数。// JDK 6、7使用;
- 1、对象的内存地址
- 2、硬编码1(通常测试使用)
- 3、序列号
- 4、对象的内存地址转换为int
- 5、线程状态参与的伪随机序列生成;
/**
* src/share/vm/prims/jvm.h
* src/share/vm/prims/jvm.cpp
*/
0. A randomly generated number. // JDK6,JDK7使用
1. A function of memory address of the object.
2. A hardcoded 1 (used for sensitivity testing.)
3. A sequence.
4. The memory address of the object, cast to int.
5. Thread state combined with xorshift (https://en.wikipedia.org/wiki/Xorshift) //JDK8使用
二、扩展:
1、使用 -XX:hashCode=x
( 0 <= x <= 5 )即可修改hashcode的默认方法策略。
2、在Hotspot中,identityHashCode
存在于MarkWord中,采用了延迟加载技术,只有在用到的时候才生成。
// ObjectSynchronizer :: FastHashCode()line 657
mark = monitor->header(); // hash值是存放在对象头中的,如果hash值不存在,则使用get_next_hash方法生成。
hash = mark->hash();
if (hash == 0) {
hash = get_next_hash(Self, obj);
}
return hash;
3、Object.hashCode()
方法和System.identityHashCode()
会让对象不能使用偏向锁
,所以如果想使用偏向锁,那就最好重写hashCode
方法。