I am learning JVM code to understand Java deeper. In synchronizer.cpp (in the get_next_hash method) there is a comment that says:
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
This is found in the in else branch when variable hashcode is not any of (0,1,2,3,4). this variable can be set via the JVM option "-XX:hashcode=n".
I wrote some code to test those hash algorithms:
public static void main(String[] args) {
long now = System.currentTimeMillis();
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
for(String s:arguments){
System.out.println(s);
}
HashMap<Integer,Object> h = new HashMap<>();
ArrayList<Object> arrayList = new ArrayList<>();
for(int i=0;i<2000000;i++){
Object o = new Object();
if(h.containsKey(o.hashCode())){
arrayList.add(o);
continue;
}
h.put(o.hashCode(),o);
}
long currentTimeMillis = System.currentTimeMillis();
System.err.println("hashcode collision:"+arrayList.size());
System.err.println(" used time "+(currentTimeMillis - now));
}
Before I ran the test, I expected I will get the fewest collisions when I set "-XX:hashcode=5", but that's not the case:
| n | algorithm |collisions|
|---|----------------|----------|
| 0 | rondom | 0 |
| 1 | addr-XOR-SHIFT | 0 |
| 2 | invarible-one | 1999999 |
| 3 | autoincrease | 0 |
| 4 | addr | 23511 |
| 5 | xor-shift | 962 |
Then I set times to 20000000 and addr-XOR-SHIFT is still 0. My question is: is it better then xor-shift? Why does jdk-8 make "-XX:hashcode=5" the default?